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

lock find when unlinking adbname->finds in dns_adb_cancelfind()

In dns_adb_cancelfind(), we need to release the find lock and
then acquire the bucket and find locks in that order, for
consistency with locking hierarchy elsehwere. Previously we
were only acquiring the bucket lock.

Also rewrote the function for better readability.
This commit is contained in:
Evan Hunt
2022-04-19 19:14:49 -07:00
committed by Ondřej Surý
parent 227b488418
commit a1e9a59e2b

View File

@@ -2662,41 +2662,15 @@ dns_adb_destroyfind(dns_adbfind_t **findp) {
free_adbfind(&find);
}
void
dns_adb_cancelfind(dns_adbfind_t *find) {
isc_event_t *ev = NULL;
isc_task_t *task = NULL;
dns_adb_t *adb = NULL;
dns_adbname_t *adbname = NULL;
dns_adbnamebucket_t *nbucket = NULL;
LOCK(&find->lock);
DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
adb = find->adb;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(!FIND_EVENTFREED(find));
REQUIRE(FIND_WANTEVENT(find));
if (find->adbname == NULL) {
goto cleanup;
}
adbname = find->adbname;
find->adbname = NULL;
nbucket = adbname->bucket;
UNLOCK(&find->lock);
LOCK(&nbucket->lock);
ISC_LIST_UNLINK(adbname->finds, find, plink);
UNLOCK(&nbucket->lock);
LOCK(&find->lock);
cleanup:
/*
* Caller must hold find lock.
*/
static void
find_sendevent(dns_adbfind_t *find) {
if (!FIND_EVENTSENT(find)) {
ev = &find->event;
task = ev->ev_sender;
isc_event_t *ev = &find->event;
isc_task_t *task = ev->ev_sender;
ev->ev_sender = find;
ev->ev_type = DNS_EVENT_ADBCANCELED;
ev->ev_destroy = event_freefind;
@@ -2709,7 +2683,45 @@ cleanup:
isc_task_sendanddetach(&task, (isc_event_t **)&ev);
}
UNLOCK(&find->lock);
}
void
dns_adb_cancelfind(dns_adbfind_t *find) {
dns_adbname_t *adbname = NULL;
DP(DEF_LEVEL, "dns_adb_cancelfind on find %p", find);
REQUIRE(DNS_ADBFIND_VALID(find));
REQUIRE(DNS_ADB_VALID(find->adb));
LOCK(&find->lock);
REQUIRE(!FIND_EVENTFREED(find));
REQUIRE(FIND_WANTEVENT(find));
adbname = find->adbname;
if (adbname == NULL) {
find_sendevent(find);
UNLOCK(&find->lock);
} else {
/*
* Release the find lock, then acquire the bucket and find
* locks in that order, to match locking hierarchy
* elsewhere.
*/
UNLOCK(&find->lock);
LOCK(&adbname->bucket->lock);
LOCK(&find->lock);
if (find->adbname != NULL) {
ISC_LIST_UNLINK(adbname->finds, find, plink);
find->adbname = NULL;
}
find_sendevent(find);
UNLOCK(&find->lock);
UNLOCK(&adbname->bucket->lock);
}
}
void