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:
@@ -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
|
||||
|
Reference in New Issue
Block a user