mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
Have the view hold a weakref until all external references are removed
so that cleanup can all be done in dns_view_weakattach().
This commit is contained in:
committed by
Ondřej Surý
parent
6353032a8a
commit
be8af3afb7
@@ -160,7 +160,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_fwdtable;
|
goto cleanup_fwdtable;
|
||||||
}
|
}
|
||||||
result = isc_refcount_init(&view->weakrefs, 0);
|
result = isc_refcount_init(&view->weakrefs, 1);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
goto cleanup_references;
|
goto cleanup_references;
|
||||||
}
|
}
|
||||||
@@ -323,6 +323,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup_weakrefs:
|
cleanup_weakrefs:
|
||||||
|
isc_refcount_decrement(&view->weakrefs, NULL);
|
||||||
isc_refcount_destroy(&view->weakrefs);
|
isc_refcount_destroy(&view->weakrefs);
|
||||||
|
|
||||||
cleanup_references:
|
cleanup_references:
|
||||||
@@ -568,23 +569,6 @@ destroy(dns_view_t *view) {
|
|||||||
isc_mem_putanddetach(&view->mctx, view, sizeof(*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
|
void
|
||||||
dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
|
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) {
|
view_flushanddetach(dns_view_t **viewp, bool flush) {
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
unsigned int refs;
|
unsigned int refs;
|
||||||
bool done = false;
|
|
||||||
|
|
||||||
REQUIRE(viewp != NULL);
|
REQUIRE(viewp != NULL);
|
||||||
view = *viewp;
|
view = *viewp;
|
||||||
|
*viewp = NULL;
|
||||||
REQUIRE(DNS_VIEW_VALID(view));
|
REQUIRE(DNS_VIEW_VALID(view));
|
||||||
|
|
||||||
if (flush)
|
if (flush)
|
||||||
@@ -642,7 +626,6 @@ view_flushanddetach(dns_view_t **viewp, bool flush) {
|
|||||||
if (view->catzs != NULL) {
|
if (view->catzs != NULL) {
|
||||||
dns_catz_catzs_detach(&view->catzs);
|
dns_catz_catzs_detach(&view->catzs);
|
||||||
}
|
}
|
||||||
done = all_done(view);
|
|
||||||
UNLOCK(&view->lock);
|
UNLOCK(&view->lock);
|
||||||
|
|
||||||
/* Need to detach zones outside view lock */
|
/* Need to detach zones outside view lock */
|
||||||
@@ -651,12 +634,9 @@ view_flushanddetach(dns_view_t **viewp, bool flush) {
|
|||||||
|
|
||||||
if (rdzone != NULL)
|
if (rdzone != NULL)
|
||||||
dns_zone_detach(&rdzone);
|
dns_zone_detach(&rdzone);
|
||||||
|
|
||||||
|
dns_view_weakdetach(&view);
|
||||||
}
|
}
|
||||||
|
|
||||||
*viewp = NULL;
|
|
||||||
|
|
||||||
if (done)
|
|
||||||
destroy(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -690,7 +670,7 @@ dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
|
|||||||
REQUIRE(DNS_VIEW_VALID(source));
|
REQUIRE(DNS_VIEW_VALID(source));
|
||||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||||
|
|
||||||
isc_refcount_increment0(&source->weakrefs, NULL);
|
isc_refcount_increment(&source->weakrefs, NULL);
|
||||||
|
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
}
|
}
|
||||||
@@ -707,20 +687,13 @@ dns_view_weakdetach(dns_view_t **viewp) {
|
|||||||
|
|
||||||
isc_refcount_decrement(&view->weakrefs, &weakrefs);
|
isc_refcount_decrement(&view->weakrefs, &weakrefs);
|
||||||
if (weakrefs == 0) {
|
if (weakrefs == 0) {
|
||||||
bool done = false;
|
|
||||||
LOCK(&view->lock);
|
|
||||||
done = all_done(view);
|
|
||||||
UNLOCK(&view->lock);
|
|
||||||
if (done) {
|
|
||||||
destroy(view);
|
destroy(view);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resolver_shutdown(isc_task_t *task, isc_event_t *event) {
|
resolver_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||||
dns_view_t *view = event->ev_arg;
|
dns_view_t *view = event->ev_arg;
|
||||||
bool done;
|
|
||||||
|
|
||||||
REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
|
REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
|
||||||
REQUIRE(DNS_VIEW_VALID(view));
|
REQUIRE(DNS_VIEW_VALID(view));
|
||||||
@@ -731,20 +704,15 @@ resolver_shutdown(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
LOCK(&view->lock);
|
LOCK(&view->lock);
|
||||||
|
|
||||||
view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
|
view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
|
||||||
done = all_done(view);
|
|
||||||
|
|
||||||
UNLOCK(&view->lock);
|
UNLOCK(&view->lock);
|
||||||
|
|
||||||
if (done)
|
dns_view_weakdetach(&view);
|
||||||
destroy(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
adb_shutdown(isc_task_t *task, isc_event_t *event) {
|
adb_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||||
dns_view_t *view = event->ev_arg;
|
dns_view_t *view = event->ev_arg;
|
||||||
bool done;
|
|
||||||
|
|
||||||
REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
|
REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
|
||||||
REQUIRE(DNS_VIEW_VALID(view));
|
REQUIRE(DNS_VIEW_VALID(view));
|
||||||
@@ -755,20 +723,15 @@ adb_shutdown(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
LOCK(&view->lock);
|
LOCK(&view->lock);
|
||||||
|
|
||||||
view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
|
view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
|
||||||
done = all_done(view);
|
|
||||||
|
|
||||||
UNLOCK(&view->lock);
|
UNLOCK(&view->lock);
|
||||||
|
|
||||||
if (done)
|
dns_view_weakdetach(&view);
|
||||||
destroy(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
req_shutdown(isc_task_t *task, isc_event_t *event) {
|
req_shutdown(isc_task_t *task, isc_event_t *event) {
|
||||||
dns_view_t *view = event->ev_arg;
|
dns_view_t *view = event->ev_arg;
|
||||||
bool done;
|
|
||||||
|
|
||||||
REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
|
REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
|
||||||
REQUIRE(DNS_VIEW_VALID(view));
|
REQUIRE(DNS_VIEW_VALID(view));
|
||||||
@@ -779,14 +742,10 @@ req_shutdown(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
LOCK(&view->lock);
|
LOCK(&view->lock);
|
||||||
|
|
||||||
view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
|
view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
|
||||||
done = all_done(view);
|
|
||||||
|
|
||||||
UNLOCK(&view->lock);
|
UNLOCK(&view->lock);
|
||||||
|
|
||||||
if (done)
|
dns_view_weakdetach(&view);
|
||||||
destroy(view);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@@ -835,6 +794,7 @@ dns_view_createresolver(dns_view_t *view,
|
|||||||
event = &view->resevent;
|
event = &view->resevent;
|
||||||
dns_resolver_whenshutdown(view->resolver, view->task, &event);
|
dns_resolver_whenshutdown(view->resolver, view->task, &event);
|
||||||
view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
|
view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
|
||||||
|
isc_refcount_increment(&view->weakrefs, NULL);
|
||||||
|
|
||||||
result = isc_mem_create(0, 0, &mctx);
|
result = isc_mem_create(0, 0, &mctx);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@@ -852,6 +812,7 @@ dns_view_createresolver(dns_view_t *view,
|
|||||||
event = &view->adbevent;
|
event = &view->adbevent;
|
||||||
dns_adb_whenshutdown(view->adb, view->task, &event);
|
dns_adb_whenshutdown(view->adb, view->task, &event);
|
||||||
view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
|
view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
|
||||||
|
isc_refcount_increment(&view->weakrefs, NULL);
|
||||||
|
|
||||||
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
|
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
|
||||||
dns_resolver_taskmgr(view->resolver),
|
dns_resolver_taskmgr(view->resolver),
|
||||||
@@ -866,6 +827,7 @@ dns_view_createresolver(dns_view_t *view,
|
|||||||
event = &view->reqevent;
|
event = &view->reqevent;
|
||||||
dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
|
dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
|
||||||
view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
|
view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
|
||||||
|
isc_refcount_increment(&view->weakrefs, NULL);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user