mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-04 00:25:29 +00:00
fix shutdown routines. The adb will go away at the right time, now.
This commit is contained in:
@@ -196,9 +196,9 @@ static void print_dns_name(FILE *, dns_name_t *);
|
|||||||
static void print_namehook_list(FILE *, dns_adbname_t *);
|
static void print_namehook_list(FILE *, dns_adbname_t *);
|
||||||
static void print_handle_list(FILE *, dns_adbname_t *);
|
static void print_handle_list(FILE *, dns_adbname_t *);
|
||||||
static inline void inc_adb_irefcnt(dns_adb_t *, isc_boolean_t);
|
static inline void inc_adb_irefcnt(dns_adb_t *, isc_boolean_t);
|
||||||
static inline void dec_adb_irefcnt(dns_adb_t *, isc_boolean_t);
|
static inline isc_boolean_t dec_adb_irefcnt(dns_adb_t *, isc_boolean_t);
|
||||||
static inline void inc_adb_erefcnt(dns_adb_t *, isc_boolean_t);
|
static inline void inc_adb_erefcnt(dns_adb_t *, isc_boolean_t);
|
||||||
static inline void dec_adb_erefcnt(dns_adb_t *, isc_boolean_t);
|
static inline isc_boolean_t dec_adb_erefcnt(dns_adb_t *, isc_boolean_t);
|
||||||
static inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
|
static inline void inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
|
||||||
isc_boolean_t);
|
isc_boolean_t);
|
||||||
static inline void dec_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
|
static inline void dec_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
|
||||||
@@ -210,6 +210,8 @@ static isc_result_t construct_name(dns_adb_t *, dns_adbhandle_t *,
|
|||||||
dns_name_t *, dns_name_t *,
|
dns_name_t *, dns_name_t *,
|
||||||
dns_adbname_t *, int, isc_stdtime_t);
|
dns_adbname_t *, int, isc_stdtime_t);
|
||||||
|
|
||||||
|
static inline isc_boolean_t check_exit(dns_adb_t *);
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want)
|
violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want)
|
||||||
{
|
{
|
||||||
@@ -221,7 +223,8 @@ violate_locking_hierarchy(isc_mutex_t *have, isc_mutex_t *want)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ADB _MUST_ be locked before calling.
|
* The ADB _MUST_ be locked before calling. Also, exit conditions must be
|
||||||
|
* checked after calling this function.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
shutdown_names(dns_adb_t *adb, isc_boolean_t kill_fetches)
|
shutdown_names(dns_adb_t *adb, isc_boolean_t kill_fetches)
|
||||||
@@ -345,6 +348,16 @@ clean_handles_at_name(dns_adbname_t *name, isc_eventtype_t evtype)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline isc_boolean_t
|
||||||
|
check_exit(dns_adb_t *adb)
|
||||||
|
{
|
||||||
|
if ((adb->irefcnt == 0)
|
||||||
|
&& (adb->erefcnt == 0)
|
||||||
|
&& (isc_mempool_getallocated(adb->ahmp) == 0))
|
||||||
|
return (ISC_TRUE);
|
||||||
|
return (ISC_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
inc_adb_irefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
inc_adb_irefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
||||||
{
|
{
|
||||||
@@ -357,20 +370,23 @@ inc_adb_irefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
|||||||
UNLOCK(&adb->lock);
|
UNLOCK(&adb->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline isc_boolean_t
|
||||||
dec_adb_irefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
dec_adb_irefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
||||||
{
|
{
|
||||||
|
isc_boolean_t kill;
|
||||||
|
|
||||||
if (lock)
|
if (lock)
|
||||||
LOCK(&adb->lock);
|
LOCK(&adb->lock);
|
||||||
|
|
||||||
INSIST(adb->irefcnt > 0);
|
INSIST(adb->irefcnt > 0);
|
||||||
adb->irefcnt--;
|
adb->irefcnt--;
|
||||||
|
|
||||||
if (adb->irefcnt == 0 && adb->erefcnt)
|
kill = check_exit(adb);
|
||||||
SIGNAL(&adb->shutdown_cond);
|
|
||||||
|
|
||||||
if (lock)
|
if (lock)
|
||||||
UNLOCK(&adb->lock);
|
UNLOCK(&adb->lock);
|
||||||
|
|
||||||
|
return (kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@@ -385,20 +401,23 @@ inc_adb_erefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
|||||||
UNLOCK(&adb->lock);
|
UNLOCK(&adb->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline isc_boolean_t
|
||||||
dec_adb_erefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
dec_adb_erefcnt(dns_adb_t *adb, isc_boolean_t lock)
|
||||||
{
|
{
|
||||||
|
isc_boolean_t kill;
|
||||||
|
|
||||||
if (lock)
|
if (lock)
|
||||||
LOCK(&adb->lock);
|
LOCK(&adb->lock);
|
||||||
|
|
||||||
INSIST(adb->erefcnt > 0);
|
INSIST(adb->erefcnt > 0);
|
||||||
adb->erefcnt--;
|
adb->erefcnt--;
|
||||||
|
|
||||||
if (adb->irefcnt == 0 && adb->erefcnt)
|
kill = check_exit(adb);
|
||||||
SIGNAL(&adb->shutdown_cond);
|
|
||||||
|
|
||||||
if (lock)
|
if (lock)
|
||||||
UNLOCK(&adb->lock);
|
UNLOCK(&adb->lock);
|
||||||
|
|
||||||
|
return (kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@@ -629,6 +648,7 @@ new_adbhandle(dns_adb_t *adb)
|
|||||||
* public members
|
* public members
|
||||||
*/
|
*/
|
||||||
h->magic = 0;
|
h->magic = 0;
|
||||||
|
h->adb = adb;
|
||||||
h->query_pending = ISC_FALSE;
|
h->query_pending = ISC_FALSE;
|
||||||
h->partial_result = ISC_FALSE;
|
h->partial_result = ISC_FALSE;
|
||||||
h->result = ISC_R_UNEXPECTED;
|
h->result = ISC_R_UNEXPECTED;
|
||||||
@@ -1029,36 +1049,25 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, dns_adb_t **newadb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_adb_destroy(dns_adb_t **adbx)
|
dns_adb_detach(dns_adb_t **adbx)
|
||||||
{
|
{
|
||||||
dns_adb_t *adb;
|
dns_adb_t *adb;
|
||||||
isc_boolean_t done;
|
isc_boolean_t kill;
|
||||||
|
|
||||||
REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx));
|
REQUIRE(adbx != NULL && DNS_ADB_VALID(*adbx));
|
||||||
|
|
||||||
adb = *adbx;
|
adb = *adbx;
|
||||||
*adbx = NULL;
|
*adbx = NULL;
|
||||||
|
|
||||||
/*
|
|
||||||
* If all lists are empty, destroy the memory used by this
|
|
||||||
* adb.
|
|
||||||
*/
|
|
||||||
LOCK(&adb->lock);
|
LOCK(&adb->lock);
|
||||||
shutdown_names(adb, ISC_TRUE);
|
|
||||||
dec_adb_erefcnt(adb, ISC_FALSE);
|
dec_adb_erefcnt(adb, ISC_FALSE);
|
||||||
do {
|
if (adb->erefcnt == 0)
|
||||||
done = ISC_TRUE;
|
shutdown_names(adb, ISC_TRUE);
|
||||||
if (adb->erefcnt != 0 || adb->irefcnt != 0)
|
kill = check_exit(adb);
|
||||||
done = ISC_FALSE;
|
|
||||||
if (isc_mempool_getallocated(adb->ahmp) > 0)
|
|
||||||
done = ISC_FALSE;
|
|
||||||
|
|
||||||
if (!done)
|
|
||||||
WAIT(&adb->shutdown_cond, &adb->lock);
|
|
||||||
} while (!done);
|
|
||||||
UNLOCK(&adb->lock);
|
UNLOCK(&adb->lock);
|
||||||
|
|
||||||
destroy(adb);
|
if (kill)
|
||||||
|
destroy(adb);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
@@ -1403,22 +1412,25 @@ dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_adb_done(dns_adb_t *adb, dns_adbhandle_t **handlep)
|
dns_adb_done(dns_adbhandle_t **handlep)
|
||||||
{
|
{
|
||||||
dns_adbhandle_t *handle;
|
dns_adbhandle_t *handle;
|
||||||
dns_adbentry_t *entry;
|
dns_adbentry_t *entry;
|
||||||
dns_adbaddrinfo_t *ai;
|
dns_adbaddrinfo_t *ai;
|
||||||
int bucket;
|
int bucket;
|
||||||
|
dns_adb_t *adb;
|
||||||
REQUIRE(DNS_ADB_VALID(adb));
|
isc_boolean_t kill;
|
||||||
|
|
||||||
REQUIRE(handlep != NULL && DNS_ADBHANDLE_VALID(*handlep));
|
REQUIRE(handlep != NULL && DNS_ADBHANDLE_VALID(*handlep));
|
||||||
handle = *handlep;
|
handle = *handlep;
|
||||||
*handlep = NULL;
|
*handlep = NULL;
|
||||||
|
|
||||||
|
LOCK(&handle->lock);
|
||||||
|
|
||||||
|
adb = handle->adb;
|
||||||
|
REQUIRE(DNS_ADB_VALID(adb));
|
||||||
REQUIRE(!ISC_LINK_LINKED(handle, next));
|
REQUIRE(!ISC_LINK_LINKED(handle, next));
|
||||||
|
|
||||||
LOCK(&handle->lock);
|
|
||||||
bucket = handle->name_bucket;
|
bucket = handle->name_bucket;
|
||||||
if (bucket == DNS_ADB_INVALIDBUCKET)
|
if (bucket == DNS_ADB_INVALIDBUCKET)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -1455,7 +1467,14 @@ dns_adb_done(dns_adb_t *adb, dns_adbhandle_t **handlep)
|
|||||||
free_adbaddrinfo(adb, &ai);
|
free_adbaddrinfo(adb, &ai);
|
||||||
ai = ISC_LIST_HEAD(handle->list);
|
ai = ISC_LIST_HEAD(handle->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOCK(&adb->lock);
|
||||||
free_adbhandle(adb, &handle);
|
free_adbhandle(adb, &handle);
|
||||||
|
kill = check_exit(adb);
|
||||||
|
UNLOCK(&adb->lock);
|
||||||
|
|
||||||
|
if (kill)
|
||||||
|
destroy(adb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1547,10 +1566,10 @@ dns_adb_dump(dns_adb_t *adb, FILE *f)
|
|||||||
if (tmpp == NULL)
|
if (tmpp == NULL)
|
||||||
tmpp = "CANNOT TRANSLATE ADDRESS!";
|
tmpp = "CANNOT TRANSLATE ADDRESS!";
|
||||||
|
|
||||||
fprintf(f, "\trefcnt %u flags %08x goodness %d"
|
fprintf(f, "\t%p: refcnt %u flags %08x goodness %d"
|
||||||
" srtt %u addr %s\n",
|
" srtt %u addr %s\n",
|
||||||
entry->refcnt, entry->flags, entry->goodness,
|
entry, entry->refcnt, entry->flags,
|
||||||
entry->srtt, tmpp);
|
entry->goodness, entry->srtt, tmpp);
|
||||||
|
|
||||||
entry = ISC_LIST_NEXT(entry, link);
|
entry = ISC_LIST_NEXT(entry, link);
|
||||||
}
|
}
|
||||||
|
@@ -136,6 +136,7 @@ struct dns_adbhandle {
|
|||||||
isc_mutex_t lock; /* locks all below */
|
isc_mutex_t lock; /* locks all below */
|
||||||
int name_bucket;
|
int name_bucket;
|
||||||
dns_adbname_t *adbname;
|
dns_adbname_t *adbname;
|
||||||
|
dns_adb_t *adb;
|
||||||
isc_event_t event;
|
isc_event_t event;
|
||||||
ISC_LINK(dns_adbhandle_t) link;
|
ISC_LINK(dns_adbhandle_t) link;
|
||||||
};
|
};
|
||||||
@@ -208,7 +209,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, dns_adb_t **newadb);
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_adb_destroy(dns_adb_t **adb);
|
dns_adb_detach(dns_adb_t **adb);
|
||||||
/*
|
/*
|
||||||
* Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests.
|
* Delete the ADB. Sets *ADB to NULL. Cancels any outstanding requests.
|
||||||
*
|
*
|
||||||
@@ -329,7 +330,7 @@ dns_adb_insert(dns_adb_t *adb, dns_name_t *host, isc_sockaddr_t *addr);
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dns_adb_done(dns_adb_t *adb, dns_adbhandle_t **handle);
|
dns_adb_done(dns_adbhandle_t **handle);
|
||||||
/*
|
/*
|
||||||
* Stops any internal lookups for this handle.
|
* Stops any internal lookups for this handle.
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user