Date: Tue, 21 Nov 2006 16:19:05 GMT From: Michael Bushkov <bushman@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 110296 for review Message-ID: <200611211619.kALGJ5Qw045908@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?200611211619.kALGJ5Qw045908>