From ca50fa02308a99f5f30b4fac892a75f8ea2fd38b Mon Sep 17 00:00:00 2001 From: Andreas Gustafsson Date: Wed, 14 Nov 2001 22:32:10 +0000 Subject: [PATCH] Partial fix for RT #2053. The potential for deadlock still exists, but it is much less likely to occur because we now only take the ADB lock when the external reference count reaches zero, not every time it is decremented. Althought this does not actually fix the bug, it at least lets us make progress on testing fixes for other bugs affecting shutdown of multithreaded servers. --- lib/dns/adb.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/lib/dns/adb.c b/lib/dns/adb.c index e1f4574207..4cafdc905e 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: adb.c,v 1.191 2001/11/12 19:05:10 gson Exp $ */ +/* $Id: adb.c,v 1.192 2001/11/14 22:32:10 gson Exp $ */ /* * Implementation notes @@ -1239,27 +1239,6 @@ inc_adb_erefcnt(dns_adb_t *adb) { UNLOCK(&adb->reflock); } -static inline void -dec_adb_erefcnt(dns_adb_t *adb, isc_boolean_t lock) { - isc_boolean_t zeroerefcnt; - - if (lock) - LOCK(&adb->lock); - - INSIST(adb->erefcnt > 0); - - LOCK(&adb->reflock); - adb->erefcnt--; - zeroerefcnt = ISC_TF(adb->erefcnt == 0); - UNLOCK(&adb->reflock); - - if (zeroerefcnt) - check_exit(adb); - - if (lock) - UNLOCK(&adb->lock); -} - static inline void inc_entry_refcnt(dns_adb_t *adb, dns_adbentry_t *entry, isc_boolean_t lock) { int bucket; @@ -2367,17 +2346,26 @@ dns_adb_attach(dns_adb_t *adb, dns_adb_t **adbx) { void dns_adb_detach(dns_adb_t **adbx) { dns_adb_t *adb; + isc_boolean_t zeroerefcnt; REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx)); adb = *adbx; *adbx = NULL; - LOCK(&adb->lock); - dec_adb_erefcnt(adb, ISC_FALSE); - if (adb->erefcnt == 0) + INSIST(adb->erefcnt > 0); + + LOCK(&adb->reflock); + adb->erefcnt--; + zeroerefcnt = ISC_TF(adb->erefcnt == 0); + UNLOCK(&adb->reflock); + + if (zeroerefcnt) { + LOCK(&adb->lock); + check_exit(adb); INSIST(adb->shutting_down); - UNLOCK(&adb->lock); + UNLOCK(&adb->lock); + } } void