2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Fixed multiple shutdown cleanup bugs in the zone object. This

involved extensive restructuring of the reference counting of
zones and related objects.

Zones now attach to their views.  To avoid a circular dependency that
would keep views from ever shutting down, this is done using the new
functions dns_view_weakattach() / dns_view_weakdetach() which
guarantee that the view will not be freed but still allow it
to be shut down.

The zones themselves now only have a single reference count, with
similar "weak" semantics.  Managed zones must now be shut down
explicitly by calling dns_zone_shutdown().  To shut down all
zones in a zone table, call dns_zt_shutdown().

The zone manager is now reference counted, weakly. To shut down the
zone manager, you must explicitly call dns_zonemgr_shutdown().
This commit is contained in:
Andreas Gustafsson
2000-05-17 19:45:36 +00:00
parent bc436be071
commit 22608315e8
8 changed files with 304 additions and 219 deletions

View File

@@ -121,6 +121,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->frozen = ISC_FALSE;
view->task = NULL;
view->references = 1;
view->weakrefs = 0;
view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
DNS_VIEWATTR_REQSHUTDOWN);
view->statickeys = NULL;
@@ -188,31 +189,11 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
return (result);
}
void
dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
/*
* Attach '*targetp' to 'source'.
*/
REQUIRE(DNS_VIEW_VALID(source));
REQUIRE(targetp != NULL && *targetp == NULL);
LOCK(&source->lock);
INSIST(source->references > 0);
source->references++;
INSIST(source->references != 0);
UNLOCK(&source->lock);
*targetp = source;
}
static inline void
destroy(dns_view_t *view) {
REQUIRE(!ISC_LINK_LINKED(view, link));
REQUIRE(view->references == 0);
REQUIRE(view->weakrefs == 0);
REQUIRE(RESSHUTDOWN(view));
REQUIRE(ADBSHUTDOWN(view));
REQUIRE(REQSHUTDOWN(view));
@@ -257,22 +238,35 @@ all_done(dns_view_t *view) {
* Caller must be holding the view lock.
*/
if (view->references == 0 && RESSHUTDOWN(view) &&
ADBSHUTDOWN(view) && REQSHUTDOWN(view))
if (view->references == 0 && view->weakrefs == 0 &&
RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
return (ISC_TRUE);
return (ISC_FALSE);
}
void
dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
REQUIRE(DNS_VIEW_VALID(source));
REQUIRE(targetp != NULL && *targetp == NULL);
LOCK(&source->lock);
INSIST(source->references > 0);
source->references++;
INSIST(source->references != 0);
UNLOCK(&source->lock);
*targetp = source;
}
void
dns_view_detach(dns_view_t **viewp) {
dns_view_t *view;
isc_boolean_t done = ISC_FALSE;
/*
* Detach '*viewp' from its view.
*/
REQUIRE(viewp != NULL);
view = *viewp;
REQUIRE(DNS_VIEW_VALID(view));
@@ -288,6 +282,7 @@ dns_view_detach(dns_view_t **viewp) {
dns_adb_shutdown(view->adb);
if (!REQSHUTDOWN(view))
dns_requestmgr_shutdown(view->requestmgr);
dns_zt_shutdown(view->zonetable);
done = all_done(view);
}
UNLOCK(&view->lock);
@@ -298,6 +293,42 @@ dns_view_detach(dns_view_t **viewp) {
destroy(view);
}
void
dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
REQUIRE(DNS_VIEW_VALID(source));
REQUIRE(targetp != NULL && *targetp == NULL);
LOCK(&source->lock);
source->weakrefs++;
UNLOCK(&source->lock);
*targetp = source;
}
void
dns_view_weakdetach(dns_view_t **viewp) {
dns_view_t *view;
isc_boolean_t done = ISC_FALSE;
REQUIRE(viewp != NULL);
view = *viewp;
REQUIRE(DNS_VIEW_VALID(view));
LOCK(&view->lock);
INSIST(view->weakrefs > 0);
view->weakrefs--;
done = all_done(view);
UNLOCK(&view->lock);
*viewp = NULL;
if (done)
destroy(view);
}
static void
resolver_shutdown(isc_task_t *task, isc_event_t *event) {
dns_view_t *view = event->ev_arg;