Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Nov 2006 17:18:16 GMT
From:      Michael Bushkov <bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 110296 for review
Message-ID:  <200611211718.kALHIG5t068612@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=110296

Change 110296 by bushman@bushman_nss_ldap_cached on 2006/11/20 13:44:08

	- pending_write_session removed
	+ reference counting for cache multipart write sessions added to simplify
	  the "clear cached" command implementation 

Affected files ...

.. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/cachelib.c#7 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/cachelib.h#5 edit
.. //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/query.c#11 edit

Differences ...

==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/cachelib.c#7 (text) ====

@@ -51,9 +51,11 @@
 static int cache_lifetime_common_continue_func(struct cache_common_entry_ *,
 	struct cache_policy_item_ *);
 static void clear_cache_entry(struct cache_entry_ *);
+static void delete_cache_mp_write_session(struct cache_mp_write_session_ *);
 static void destroy_cache_entry(struct cache_entry_ *);
 static void destroy_cache_mp_read_session(struct cache_mp_read_session_ *);
 static void destroy_cache_mp_write_session(struct cache_mp_write_session_ *);
+static void destroy_queued_cache_mp_write_sessions(struct cache_mp_entry_ *);
 static int entries_bsearch_cmp_func(const void *, const void *);
 static int entries_qsort_cmp_func(const void *, const void *);
 static struct cache_entry_ ** find_cache_entry_p(struct cache_ *,
@@ -182,6 +184,21 @@
 }
 
 static void
+delete_cache_mp_write_session(struct cache_mp_write_session_ *ws)
+{
+	
+	TRACE_IN(delete_cache_mp_write_session);
+	assert(ws != NULL);
+	assert(ws->parent_entry != NULL);
+	
+	if (ws->parent_entry->rs_size == 0)
+		destroy_cache_mp_write_session(ws);
+	else
+		TAILQ_INSERT_HEAD(&ws->parent_entry->del_ws_head, ws, entries);
+	TRACE_OUT(delete_cache_mp_write_session);
+}
+
+static void
 destroy_cache_mp_write_session(struct cache_mp_write_session_ *ws)
 {
 
@@ -200,6 +217,26 @@
 	TRACE_OUT(destroy_cache_mp_write_session);
 }
 
+static void 
+destroy_queued_cache_mp_write_sessions(struct cache_mp_entry_ *entry)
+{
+	
+	struct cache_mp_write_session_ *ws, *nws;
+
+	TRACE_IN(destroy_queued_cache_mp_write_sessions);
+	assert(entry != NULL);
+	
+	nws = NULL;
+	TAILQ_FOREACH_SAFE(ws, &entry->del_ws_head, entries, nws) {
+		if (ws->ref_counter == 0) {
+			TAILQ_REMOVE(&entry->del_ws_head, ws, entries);
+			destroy_cache_mp_write_session(ws);
+		}
+	}
+	
+	TRACE_OUT(destroy_queued_cache_mp_write_sessions);
+}
+
 static void
 destroy_cache_mp_read_session(struct cache_mp_read_session_ *rs)
 {
@@ -258,6 +295,12 @@
 			TAILQ_REMOVE(&mp_entry->ws_head, ws, entries);
 			destroy_cache_mp_write_session(ws);
 		}
+		
+		while (!TAILQ_EMPTY(&mp_entry->del_ws_head)) {
+			ws = TAILQ_FIRST(&mp_entry->del_ws_head);
+			TAILQ_REMOVE(&mp_entry->del_ws_head, ws, entries);
+			destroy_cache_mp_write_session(ws);
+		}
 
 		while (!TAILQ_EMPTY(&mp_entry->rs_head)) {
 			rs = TAILQ_FIRST(&mp_entry->rs_head);
@@ -268,10 +311,6 @@
 		if (mp_entry->completed_write_session != NULL)
 			destroy_cache_mp_write_session(
 				mp_entry->completed_write_session);
-
-		if (mp_entry->pending_write_session != NULL)
-			destroy_cache_mp_write_session(
-				mp_entry->pending_write_session);
 	}
 
 	free(entry->name);
@@ -322,24 +361,17 @@
 	} else {
 		mp_entry = (struct cache_mp_entry_ *)entry;
 
-		/*
-		 * NOTE: currently multipart entries are cleared only if 
-		 * there are no opened read sessions. It leads to possible
-		 * failues of cache clearing requests. Possibly, some simple
-		 * reference counting should be used to avoid this
-		 */
-		if (mp_entry->rs_size == 0) {
-			if (mp_entry->completed_write_session != NULL) {
-				destroy_cache_mp_write_session(
-					mp_entry->completed_write_session);
-				mp_entry->completed_write_session = NULL;
-			}
+		if (mp_entry->completed_write_session != NULL) {
+			delete_cache_mp_write_session(
+				mp_entry->completed_write_session);
+			mp_entry->completed_write_session = NULL;
+		}
+		destroy_queued_cache_mp_write_sessions(mp_entry);
 
-			memset(&mp_entry->creation_time, 0,
-				sizeof(struct timeval));
-			memset(&mp_entry->last_request_time, 0,
-				sizeof(struct timeval));
-		}
+		memset(&mp_entry->creation_time, 0,
+			sizeof(struct timeval));
+		memset(&mp_entry->last_request_time, 0,
+			sizeof(struct timeval));
 	}
 }
 
@@ -693,6 +725,7 @@
 		new_mp_entry->name = new_mp_entry->mp_params.entry_name;
 
 		TAILQ_INIT(&new_mp_entry->ws_head);
+		TAILQ_INIT(&new_mp_entry->del_ws_head);
 		TAILQ_INIT(&new_mp_entry->rs_head);
 
 		new_mp_entry->get_time_func = the_cache->params.get_time_func;
@@ -1097,25 +1130,12 @@
 	TAILQ_REMOVE(&ws->parent_entry->ws_head, ws, entries);
 	--ws->parent_entry->ws_size;
 
-	if (ws->parent_entry->completed_write_session == NULL) {
-		/*
-		 * If there is no completed session yet, this will be the one
-		 */
-		ws->parent_entry->get_time_func(
-	    		&ws->parent_entry->creation_time);
-		ws->parent_entry->completed_write_session = ws;
-	} else {
-		/*
-		 * If there is a completed session, then we'll save our session
-		 * as a pending session. If there is already a pending session,
-		 * it would be destroyed.
-		 */
-		if (ws->parent_entry->pending_write_session != NULL)
-			destroy_cache_mp_write_session(
-				ws->parent_entry->pending_write_session);
+	if (ws->parent_entry->completed_write_session != NULL)
+		delete_cache_mp_write_session(
+		    ws->parent_entry->completed_write_session);
 
-		ws->parent_entry->pending_write_session = ws;
-	}
+	ws->parent_entry->get_time_func(&ws->parent_entry->creation_time);
+	ws->parent_entry->completed_write_session = ws;
 	TRACE_OUT(close_cache_mp_write_session);
 }
 
@@ -1126,7 +1146,7 @@
 struct cache_mp_read_session_ *
 open_cache_mp_read_session(struct cache_entry_ *entry)
 {
-	struct cache_mp_entry_			*mp_entry;
+	struct cache_mp_entry_		*mp_entry;
 	struct cache_mp_read_session_	*retval;
 
 	TRACE_IN(open_cache_mp_read_session);
@@ -1157,6 +1177,8 @@
 	}
 	memset(retval, 0, sizeof(struct cache_mp_read_session_));
 
+	++mp_entry->completed_write_session->ref_counter;	
+	retval->linked_ws = mp_entry->completed_write_session;
 	retval->parent_entry = mp_entry;
 	retval->current_item = TAILQ_FIRST(
 		&mp_entry->completed_write_session->items);
@@ -1233,16 +1255,9 @@
 	assert(rs->parent_entry != NULL);
 
 	TAILQ_REMOVE(&rs->parent_entry->rs_head, rs, entries);
-	--rs->parent_entry->rs_size;
-
-	if ((rs->parent_entry->rs_size == 0) &&
-		(rs->parent_entry->pending_write_session != NULL)) {
-		destroy_cache_mp_write_session(
-			rs->parent_entry->completed_write_session);
-		rs->parent_entry->completed_write_session =
-			rs->parent_entry->pending_write_session;
-		rs->parent_entry->pending_write_session = NULL;
-	}
+	--rs->parent_entry->rs_size;	
+	--rs->linked_ws->ref_counter;
+	destroy_queued_cache_mp_write_sessions(rs->parent_entry);
 
 	destroy_cache_mp_read_session(rs);
 	TRACE_OUT(close_cache_mp_read_session);

==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/cachelib.h#5 (text) ====

@@ -183,12 +183,14 @@
 	size_t	items_size;
 
 	TAILQ_ENTRY(cache_mp_write_session_) entries;
+	int	ref_counter;
 };
 
 struct cache_mp_read_session_
 {
 	struct cache_mp_entry_ *parent_entry;
 	struct cache_mp_data_item_ *current_item;
+	struct cache_mp_write_session_ *linked_ws; /* Data are read from it*/
 
 	TAILQ_ENTRY(cache_mp_read_session_) entries;
 };
@@ -204,9 +206,13 @@
 	TAILQ_HEAD(write_sessions_head, cache_mp_write_session_) ws_head;
 	size_t	ws_size;
 
+	/* Write sessions, queued for deletion */
+	TAILQ_HEAD(del_write_sessions_head, cache_mp_write_session_)
+		del_ws_head;
+
 	/* All opened read sessions */
 	TAILQ_HEAD(read_sessions_head, cache_mp_read_session_) rs_head;
-	size_t	rs_size;
+	size_t	rs_size;	
 
 	/*
 	 * completed_write_session is the committed write sessions. All read
@@ -218,7 +224,6 @@
 	 * the read sessions.
 	 */
 	struct cache_mp_write_session_	*completed_write_session;
-	struct cache_mp_write_session_	*pending_write_session;
 	struct timeval	creation_time;
 	struct timeval	last_request_time;
 

==== //depot/projects/soc2006/nss_ldap_cached/src/usr.sbin/cached/query.c#11 (text) ====

@@ -1097,6 +1097,7 @@
 		break;
 	default:
 		transform_response->error_code = -1;
+		break;
 	}
 
 fin:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611211718.kALHIG5t068612>