diff --git a/lib/dns/view.c b/lib/dns/view.c index fa159c977c..a1a4301b5d 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -160,7 +160,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, if (result != ISC_R_SUCCESS) { goto cleanup_fwdtable; } - result = isc_refcount_init(&view->weakrefs, 0); + result = isc_refcount_init(&view->weakrefs, 1); if (result != ISC_R_SUCCESS) { goto cleanup_references; } @@ -323,6 +323,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, } cleanup_weakrefs: + isc_refcount_decrement(&view->weakrefs, NULL); isc_refcount_destroy(&view->weakrefs); cleanup_references: @@ -568,23 +569,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) { @@ -600,10 +584,10 @@ static void view_flushanddetach(dns_view_t **viewp, bool flush) { dns_view_t *view; unsigned int refs; - bool done = false; REQUIRE(viewp != NULL); view = *viewp; + *viewp = NULL; REQUIRE(DNS_VIEW_VALID(view)); if (flush) @@ -642,7 +626,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 */ @@ -651,12 +634,9 @@ view_flushanddetach(dns_view_t **viewp, bool flush) { if (rdzone != NULL) dns_zone_detach(&rdzone); + + dns_view_weakdetach(&view); } - - *viewp = NULL; - - if (done) - destroy(view); } void @@ -690,7 +670,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, NULL); + isc_refcount_increment(&source->weakrefs, NULL); *targetp = source; } @@ -707,20 +687,13 @@ dns_view_weakdetach(dns_view_t **viewp) { isc_refcount_decrement(&view->weakrefs, &weakrefs); if (weakrefs == 0) { - 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)); @@ -731,20 +704,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)); @@ -755,20 +723,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)); @@ -779,14 +742,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 @@ -835,6 +794,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, NULL); result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) { @@ -852,6 +812,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, NULL); result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, dns_resolver_taskmgr(view->resolver), @@ -866,6 +827,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, NULL); return (ISC_R_SUCCESS); }