PERFORCE change 110296 for review
Michael Bushkov
bushman at FreeBSD.org
Tue Nov 21 16:20:30 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=110296
Change 110296 by bushman at 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:
More information about the p4-projects
mailing list