|
|
900526 |
From e7a2611c555e03314ac4f7960044b05cce040364 Mon Sep 17 00:00:00 2001
|
|
|
900526 |
From: Mark Andrews <marka@isc.org>
|
|
|
900526 |
Date: Thu, 31 Jul 2014 11:38:11 +1000
|
|
|
900526 |
Subject: [PATCH] 3905. [bug] Address deadlock between view.c and adb.c. [RT
|
|
|
900526 |
#36341]
|
|
|
900526 |
MIME-Version: 1.0
|
|
|
900526 |
Content-Type: text/plain; charset=UTF-8
|
|
|
900526 |
Content-Transfer-Encoding: 8bit
|
|
|
900526 |
|
|
|
900526 |
Original-commit: 5e746ab61ed8158f784b86111fef95581a08b7dd
|
|
|
900526 |
Signed-off-by: Petr Menšík <pemensik@redhat.com>
|
|
|
900526 |
---
|
|
|
900526 |
lib/dns/adb.c | 57 +++++++++++++++++++++++++++++++++++++++++----------------
|
|
|
900526 |
1 file changed, 41 insertions(+), 16 deletions(-)
|
|
|
900526 |
|
|
|
900526 |
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
|
|
|
900526 |
index a6da94d..ac89e66 100644
|
|
|
900526 |
--- a/lib/dns/adb.c
|
|
|
900526 |
+++ b/lib/dns/adb.c
|
|
|
900526 |
@@ -15,8 +15,6 @@
|
|
|
900526 |
* PERFORMANCE OF THIS SOFTWARE.
|
|
|
900526 |
*/
|
|
|
900526 |
|
|
|
900526 |
-/* $Id: adb.c,v 1.264 2011/12/05 17:10:51 each Exp $ */
|
|
|
900526 |
-
|
|
|
900526 |
/*! \file
|
|
|
900526 |
*
|
|
|
900526 |
* \note
|
|
|
900526 |
@@ -157,7 +155,7 @@ struct dns_adb {
|
|
|
900526 |
unsigned int *entry_refcnt;
|
|
|
900526 |
|
|
|
900526 |
isc_event_t cevent;
|
|
|
900526 |
- isc_boolean_t cevent_sent;
|
|
|
900526 |
+ isc_boolean_t cevent_out;
|
|
|
900526 |
isc_boolean_t shutting_down;
|
|
|
900526 |
isc_eventlist_t whenshutdown;
|
|
|
900526 |
isc_event_t growentries;
|
|
|
900526 |
@@ -322,6 +320,7 @@ static inline isc_boolean_t unlink_entry(dns_adb_t *, dns_adbentry_t *);
|
|
|
900526 |
static isc_boolean_t kill_name(dns_adbname_t **, isc_eventtype_t);
|
|
|
900526 |
static void water(void *, int);
|
|
|
900526 |
static void dump_entry(FILE *, dns_adbentry_t *, isc_boolean_t, isc_stdtime_t);
|
|
|
900526 |
+static void shutdown_task(isc_task_t *task, isc_event_t *ev);
|
|
|
900526 |
|
|
|
900526 |
/*
|
|
|
900526 |
* MUST NOT overlap DNS_ADBFIND_* flags!
|
|
|
900526 |
@@ -1499,10 +1498,13 @@ check_exit(dns_adb_t *adb) {
|
|
|
900526 |
* If there aren't any external references either, we're
|
|
|
900526 |
* done. Send the control event to initiate shutdown.
|
|
|
900526 |
*/
|
|
|
900526 |
- INSIST(!adb->cevent_sent); /* Sanity check. */
|
|
|
900526 |
+ INSIST(!adb->cevent_out); /* Sanity check. */
|
|
|
900526 |
+ ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
|
|
|
900526 |
+ DNS_EVENT_ADBCONTROL, shutdown_task, adb,
|
|
|
900526 |
+ adb, NULL, NULL);
|
|
|
900526 |
event = &adb->cevent;
|
|
|
900526 |
isc_task_send(adb->task, &event);
|
|
|
900526 |
- adb->cevent_sent = ISC_TRUE;
|
|
|
900526 |
+ adb->cevent_out = ISC_TRUE;
|
|
|
900526 |
}
|
|
|
900526 |
}
|
|
|
900526 |
|
|
|
900526 |
@@ -2431,10 +2433,9 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
|
|
|
900526 |
adb->view = view;
|
|
|
900526 |
adb->taskmgr = taskmgr;
|
|
|
900526 |
adb->next_cleanbucket = 0;
|
|
|
900526 |
- ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
|
|
|
900526 |
- DNS_EVENT_ADBCONTROL, shutdown_task, adb,
|
|
|
900526 |
- adb, NULL, NULL);
|
|
|
900526 |
- adb->cevent_sent = ISC_FALSE;
|
|
|
900526 |
+ ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent),
|
|
|
900526 |
+ 0, NULL, 0, NULL, NULL, NULL, NULL, NULL);
|
|
|
900526 |
+ adb->cevent_out = ISC_FALSE;
|
|
|
900526 |
adb->shutting_down = ISC_FALSE;
|
|
|
900526 |
ISC_LIST_INIT(adb->whenshutdown);
|
|
|
900526 |
|
|
|
900526 |
@@ -2468,7 +2469,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
|
|
|
900526 |
"intializing table sizes to %u\n",
|
|
|
900526 |
nbuckets[11]);
|
|
|
900526 |
adb->nentries = nbuckets[11];
|
|
|
900526 |
- adb->nnames= nbuckets[11];
|
|
|
900526 |
+ adb->nnames = nbuckets[11];
|
|
|
900526 |
|
|
|
900526 |
}
|
|
|
900526 |
|
|
|
900526 |
@@ -2741,9 +2742,28 @@ dns_adb_whenshutdown(dns_adb_t *adb, isc_task_t *task, isc_event_t **eventp) {
|
|
|
900526 |
UNLOCK(&adb->lock);
|
|
|
900526 |
}
|
|
|
900526 |
|
|
|
900526 |
+static void
|
|
|
900526 |
+shutdown_stage2(isc_task_t *task, isc_event_t *event) {
|
|
|
900526 |
+ dns_adb_t *adb;
|
|
|
900526 |
+
|
|
|
900526 |
+ UNUSED(task);
|
|
|
900526 |
+
|
|
|
900526 |
+ adb = event->ev_arg;
|
|
|
900526 |
+ INSIST(DNS_ADB_VALID(adb));
|
|
|
900526 |
+
|
|
|
900526 |
+ LOCK(&adb->lock);
|
|
|
900526 |
+ INSIST(adb->shutting_down);
|
|
|
900526 |
+ adb->cevent_out = ISC_FALSE;
|
|
|
900526 |
+ (void)shutdown_names(adb);
|
|
|
900526 |
+ (void)shutdown_entries(adb);
|
|
|
900526 |
+ if (dec_adb_irefcnt(adb))
|
|
|
900526 |
+ check_exit(adb);
|
|
|
900526 |
+ UNLOCK(&adb->lock);
|
|
|
900526 |
+}
|
|
|
900526 |
+
|
|
|
900526 |
void
|
|
|
900526 |
dns_adb_shutdown(dns_adb_t *adb) {
|
|
|
900526 |
- isc_boolean_t need_check_exit;
|
|
|
900526 |
+ isc_event_t *event;
|
|
|
900526 |
|
|
|
900526 |
/*
|
|
|
900526 |
* Shutdown 'adb'.
|
|
|
900526 |
@@ -2754,11 +2774,16 @@ dns_adb_shutdown(dns_adb_t *adb) {
|
|
|
900526 |
if (!adb->shutting_down) {
|
|
|
900526 |
adb->shutting_down = ISC_TRUE;
|
|
|
900526 |
isc_mem_setwater(adb->mctx, water, adb, 0, 0);
|
|
|
900526 |
- need_check_exit = shutdown_names(adb);
|
|
|
900526 |
- if (!need_check_exit)
|
|
|
900526 |
- need_check_exit = shutdown_entries(adb);
|
|
|
900526 |
- if (need_check_exit)
|
|
|
900526 |
- check_exit(adb);
|
|
|
900526 |
+ /*
|
|
|
900526 |
+ * Isolate shutdown_names and shutdown_entries calls.
|
|
|
900526 |
+ */
|
|
|
900526 |
+ inc_adb_irefcnt(adb);
|
|
|
900526 |
+ ISC_EVENT_INIT(&adb->cevent, sizeof(adb->cevent), 0, NULL,
|
|
|
900526 |
+ DNS_EVENT_ADBCONTROL, shutdown_stage2, adb,
|
|
|
900526 |
+ adb, NULL, NULL);
|
|
|
900526 |
+ adb->cevent_out = ISC_TRUE;
|
|
|
900526 |
+ event = &adb->cevent;
|
|
|
900526 |
+ isc_task_send(adb->task, &event);
|
|
|
900526 |
}
|
|
|
900526 |
|
|
|
900526 |
UNLOCK(&adb->lock);
|
|
|
900526 |
--
|
|
|
900526 |
2.9.3
|
|
|
900526 |
|