]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Have the view hold a weakref until all external references are removed
authorMark Andrews <marka@isc.org>
Tue, 6 Aug 2019 02:40:04 +0000 (12:40 +1000)
committerOndřej Surý <ondrej@sury.org>
Wed, 7 Aug 2019 10:43:12 +0000 (12:43 +0200)
so that cleanup can all be done in dns_view_weakattach().

(cherry picked from commit be8af3afb711a04ac140b1debce3b950922d714f)
(cherry picked from commit e3946327035832ec03c064410e5c6881841f8f6f)

lib/dns/view.c

index 239f9d2741699dc36a6b4e6449a5758a53e4cdac..461722bd6a7e292ad6508c3d121d180152abd0d4 100644 (file)
@@ -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);
 }