Mercurial > illumos > illumos-gate
changeset 4138:c1afdb77f1fa
6534136 nsc_ctx_t's waiters list is poorly protected
6537512 nscd hangs desktop at password prompt with gdm
6550191 nscd should update the queries-queued (wait_count) counter
author | michen |
---|---|
date | Mon, 30 Apr 2007 14:34:54 -0700 |
parents | 8bbbcf1ea205 |
children | 5f9029783cc0 |
files | usr/src/cmd/nscd/cache.c usr/src/cmd/nscd/cache.h usr/src/cmd/nscd/nscd_wait.c |
diffstat | 3 files changed, 40 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/nscd/cache.c Mon Apr 30 13:20:49 2007 -0700 +++ b/usr/src/cmd/nscd/cache.c Mon Apr 30 14:34:54 2007 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1514,8 +1514,7 @@ "%s: no clearance to wait\n"); } /* yes can wait */ - (void) nscd_wait(&ctx->wait, &nscdb->db_mutex, - &this_stats->status); + (void) nscd_wait(ctx, nscdb, this_entry); (void) _nscd_release_clearance(&ctx->throttle_sema); continue; } @@ -1557,7 +1556,7 @@ (void) _nscd_release_clearance(&ctx->throttle_sema); /* signal waiting threads */ - (void) nscd_signal(&ctx->wait, &this_stats->status); + (void) nscd_signal(ctx, nscdb, this_entry); _NSCD_LOG(NSCD_LOG_CACHE, NSCD_LOG_LEVEL_DEBUG) (me, "%s: name service lookup status = %d\n",
--- a/usr/src/cmd/nscd/cache.h Mon Apr 30 13:20:49 2007 -0700 +++ b/usr/src/cmd/nscd/cache.h Mon Apr 30 14:34:54 2007 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -117,15 +117,6 @@ } nsc_action_t; /* - * Structure to handle waiting for pending name service requests - */ -typedef struct waiter { - cond_t w_waitcv; - uint8_t *w_key; - struct waiter *w_next, *w_prev; -} waiter_t; - -/* * What each entry in the nameserver cache looks like. */ @@ -152,6 +143,16 @@ } nsc_keephot_t; /* + * Structure to handle waiting for pending name service requests + */ +typedef struct waiter { + cond_t w_waitcv; + uint8_t w_signaled; + nsc_entry_t *w_key; + struct waiter *w_next, *w_prev; +} waiter_t; + +/* * Macros used by hash table * * _NSC_HTSIZE_PRIMES are prime numbers that are used as hash table @@ -249,6 +250,7 @@ int dbop; char *name; mutex_t db_mutex; + waiter_t db_wait; /* lookup wait CV */ int htsize; enum hash_type { nsc_ht_default = 0, @@ -290,7 +292,6 @@ const char *file_name; /* filename for check_files */ int db_count; /* number of caches */ nsc_db_t *nsc_db[_NSC_MAX_DB]; /* caches */ - waiter_t wait; /* lookup wait CV */ sema_t throttle_sema; /* throttle lookups */ sema_t revalidate_sema; /* revalidation threads */ nscd_bool_t revalidate_on; /* reval. thread started */ @@ -329,8 +330,8 @@ extern void tnrhdb_init_ctx(nsc_ctx_t *); /* Functions used to throttle threads */ -extern int nscd_wait(waiter_t *, mutex_t *, uint8_t *); -extern int nscd_signal(waiter_t *, uint8_t *); +extern int nscd_wait(nsc_ctx_t *, nsc_db_t *, nsc_entry_t *); +extern int nscd_signal(nsc_ctx_t *, nsc_db_t *, nsc_entry_t *); /* Cache creation and initialization */ extern nscd_rc_t init_cache();
--- a/usr/src/cmd/nscd/nscd_wait.c Mon Apr 30 13:20:49 2007 -0700 +++ b/usr/src/cmd/nscd/nscd_wait.c Mon Apr 30 14:34:54 2007 -0700 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,19 +32,26 @@ #include "cache.h" int -nscd_wait(waiter_t *wchan, mutex_t *lock, uint8_t *key) +nscd_wait(nsc_ctx_t *ctx, nsc_db_t *nscdb, nsc_entry_t *entry) { - waiter_t mywait; + waiter_t mywait; + waiter_t *wchan = &nscdb->db_wait; + (void) cond_init(&(mywait.w_waitcv), USYNC_THREAD, 0); - mywait.w_key = key; + mywait.w_key = entry; + mywait.w_signaled = 0; mywait.w_next = wchan->w_next; mywait.w_prev = wchan; if (mywait.w_next) mywait.w_next->w_prev = &mywait; wchan->w_next = &mywait; - while (*key & ST_PENDING) - (void) cond_wait(&(mywait.w_waitcv), lock); + (void) mutex_lock(&ctx->stats_mutex); + ctx->stats.wait_count++; + (void) mutex_unlock(&ctx->stats_mutex); + + while (!mywait.w_signaled) + (void) cond_wait(&(mywait.w_waitcv), &nscdb->db_mutex); if (mywait.w_prev) mywait.w_prev->w_next = mywait.w_next; if (mywait.w_next) @@ -53,14 +60,20 @@ } int -nscd_signal(waiter_t *wchan, uint8_t *key) +nscd_signal(nsc_ctx_t *ctx, nsc_db_t *nscdb, nsc_entry_t *entry) { - int c = 0; - waiter_t *tmp = wchan->w_next; + int c = 0; + waiter_t *wchan = &nscdb->db_wait; + waiter_t *tmp = wchan->w_next; while (tmp) { - if (tmp->w_key == key) { + if (tmp->w_key == entry) { (void) cond_signal(&(tmp->w_waitcv)); + tmp->w_signaled = 1; + + (void) mutex_lock(&ctx->stats_mutex); + ctx->stats.wait_count--; + (void) mutex_unlock(&ctx->stats_mutex); c++; } tmp = tmp->w_next;