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

use separate barriers for "stop" and "listen" operations

On some platforms, when a synchronizing barrier is cleared, one
thread can progress while other threads are still in the process
of releasing the barrier. If a barrier is reused by the progressing
thread during this window, it can cause a deadlock. This can occur if,
for example, we stop listening immediately after we start, because the
stop and listen functions both use socket->barrier.  This has been
addressed by using separate barrier objects for stop and listen.
This commit is contained in:
Evan Hunt
2023-01-07 16:30:21 -08:00
parent f0bba87db0
commit 9c577e10c3
4 changed files with 14 additions and 11 deletions

View File

@@ -676,8 +676,9 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
#endif
isc__nm_streamdns_cleanup_data(sock);
if (sock->barrier_initialised) {
isc_barrier_destroy(&sock->barrier);
if (sock->barriers_initialised) {
isc_barrier_destroy(&sock->listen_barrier);
isc_barrier_destroy(&sock->stop_barrier);
}
sock->magic = 0;
@@ -2021,8 +2022,9 @@ isc__nmsocket_stop(isc_nmsocket_t *listener) {
void
isc__nmsocket_barrier_init(isc_nmsocket_t *listener) {
REQUIRE(listener->nchildren > 0);
isc_barrier_init(&listener->barrier, listener->nchildren);
listener->barrier_initialised = true;
isc_barrier_init(&listener->listen_barrier, listener->nchildren);
isc_barrier_init(&listener->stop_barrier, listener->nchildren);
listener->barriers_initialised = true;
}
void
@@ -2032,7 +2034,7 @@ isc__nm_async_sockstop(isc__networker_t *worker, isc__netievent_t *ev0) {
UNUSED(worker);
(void)atomic_fetch_sub(&listener->rchildren, 1);
isc_barrier_wait(&listener->barrier);
isc_barrier_wait(&listener->stop_barrier);
}
void