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

ensure interlocked netmgr events run on worker[0]

Network manager events that require interlock (pause, resume, listen)
are now always executed in the same worker thread, mgr->workers[0],
to prevent races.

"stoplistening" events no longer require interlock.
This commit is contained in:
Ondřej Surý
2021-05-06 16:11:43 +02:00
committed by Evan Hunt
parent c44423127d
commit 365c6a9851
11 changed files with 76 additions and 111 deletions

View File

@@ -437,6 +437,10 @@ isc_nm_pause(isc_nm_t *mgr) {
isc__nm_acquire_interlocked_force(mgr);
if (isc__nm_in_netthread()) {
REQUIRE(isc_nm_tid() == 0);
}
for (int i = 0; i < mgr->nworkers; i++) {
isc__networker_t *worker = &mgr->workers[i];
if (i == isc_nm_tid()) {
@@ -447,8 +451,8 @@ isc_nm_pause(isc_nm_t *mgr) {
}
if (isc__nm_in_netthread()) {
atomic_fetch_add(&mgr->workers_paused, 1);
isc_barrier_wait(&mgr->pausing);
drain_priority_queue(&mgr->workers[isc_nm_tid()]);
}
LOCK(&mgr->lock);
@@ -481,6 +485,11 @@ isc_nm_resume(isc_nm_t *mgr) {
REQUIRE(VALID_NM(mgr));
REQUIRE(atomic_load(&mgr->paused));
if (isc__nm_in_netthread()) {
REQUIRE(isc_nm_tid() == 0);
drain_priority_queue(&mgr->workers[isc_nm_tid()]);
}
for (int i = 0; i < mgr->nworkers; i++) {
isc__networker_t *worker = &mgr->workers[i];
if (i == isc_nm_tid()) {