From: Mark Andrews Date: Tue, 6 Aug 2019 02:40:04 +0000 (+1000) Subject: Have the view hold a weakref until all external references are removed X-Git-Tag: v9.15.3~8^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3cd04b95a998b95a4844d900f1bd12378abc9b0;p=thirdparty%2Fbind9.git Have the view hold a weakref until all external references are removed so that cleanup can all be done in dns_view_weakattach(). (cherry picked from commit be8af3afb711a04ac140b1debce3b950922d714f) (cherry picked from commit e3946327035832ec03c064410e5c6881841f8f6f) --- diff --git a/lib/dns/view.c b/lib/dns/view.c index 239f9d27416..461722bd6a7 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -139,7 +139,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->frozen = false; view->task = NULL; isc_refcount_init(&view->references, 1); - isc_refcount_init(&view->weakrefs, 0); + isc_refcount_init(&view->weakrefs, 1); view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| DNS_VIEWATTR_REQSHUTDOWN); view->statickeys = NULL; @@ -305,6 +305,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, } cleanup_weakrefs: + isc_refcount_decrement(&view->weakrefs); isc_refcount_destroy(&view->weakrefs); isc_refcount_decrement(&view->references); @@ -551,23 +552,6 @@ destroy(dns_view_t *view) { isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); } -/* - * Return true iff 'view' may be freed. - * The caller must be holding the view lock. - */ -static bool -all_done(dns_view_t *view) { - - if (isc_refcount_current(&view->references) == 0 && - isc_refcount_current(&view->weakrefs) == 0 && - RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) - { - return (true); - } - - return (false); -} - void dns_view_attach(dns_view_t *source, dns_view_t **targetp) { @@ -589,7 +573,6 @@ view_flushanddetach(dns_view_t **viewp, bool flush) { view->flush = flush; } - bool done = false; if (isc_refcount_decrement(&view->references) == 1) { dns_zone_t *mkzone = NULL, *rdzone = NULL; @@ -627,7 +610,6 @@ view_flushanddetach(dns_view_t **viewp, bool flush) { if (view->catzs != NULL) { dns_catz_catzs_detach(&view->catzs); } - done = all_done(view); UNLOCK(&view->lock); /* Need to detach zones outside view lock */ @@ -638,12 +620,8 @@ view_flushanddetach(dns_view_t **viewp, bool flush) { if (rdzone != NULL) { dns_zone_detach(&rdzone); } - } - - *viewp = NULL; - if (done) { - destroy(view); + dns_view_weakdetach(&view); } } @@ -678,7 +656,7 @@ dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { REQUIRE(DNS_VIEW_VALID(source)); REQUIRE(targetp != NULL && *targetp == NULL); - isc_refcount_increment0(&source->weakrefs); + isc_refcount_increment(&source->weakrefs); *targetp = source; } @@ -693,20 +671,13 @@ dns_view_weakdetach(dns_view_t **viewp) { *viewp = NULL; if (isc_refcount_decrement(&view->weakrefs) == 1) { - bool done = false; - LOCK(&view->lock); - done = all_done(view); - UNLOCK(&view->lock); - if (done) { - destroy(view); - } + destroy(view); } } static void resolver_shutdown(isc_task_t *task, isc_event_t *event) { dns_view_t *view = event->ev_arg; - bool done; REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); REQUIRE(DNS_VIEW_VALID(view)); @@ -717,20 +688,15 @@ resolver_shutdown(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); LOCK(&view->lock); - view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; - done = all_done(view); - UNLOCK(&view->lock); - if (done) - destroy(view); + dns_view_weakdetach(&view); } static void adb_shutdown(isc_task_t *task, isc_event_t *event) { dns_view_t *view = event->ev_arg; - bool done; REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); REQUIRE(DNS_VIEW_VALID(view)); @@ -741,20 +707,15 @@ adb_shutdown(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); LOCK(&view->lock); - view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; - done = all_done(view); - UNLOCK(&view->lock); - if (done) - destroy(view); + dns_view_weakdetach(&view); } static void req_shutdown(isc_task_t *task, isc_event_t *event) { dns_view_t *view = event->ev_arg; - bool done; REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); REQUIRE(DNS_VIEW_VALID(view)); @@ -765,14 +726,10 @@ req_shutdown(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); LOCK(&view->lock); - view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; - done = all_done(view); - UNLOCK(&view->lock); - if (done) - destroy(view); + dns_view_weakdetach(&view); } isc_result_t @@ -821,6 +778,7 @@ dns_view_createresolver(dns_view_t *view, event = &view->resevent; dns_resolver_whenshutdown(view->resolver, view->task, &event); view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; + isc_refcount_increment(&view->weakrefs); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) { @@ -838,6 +796,7 @@ dns_view_createresolver(dns_view_t *view, event = &view->adbevent; dns_adb_whenshutdown(view->adb, view->task, &event); view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; + isc_refcount_increment(&view->weakrefs); result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, dns_resolver_taskmgr(view->resolver), @@ -852,6 +811,7 @@ dns_view_createresolver(dns_view_t *view, event = &view->reqevent; dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; + isc_refcount_increment(&view->weakrefs); return (ISC_R_SUCCESS); }