mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Complete the isc_nmhandle_detach() in the worker thread.
isc_nmhandle_detach() needs to complete in the same thread as shutdown_walk_cb() to avoid a race. Clear the caller's pointer then pass control to the worker if necessary. WARNING: ThreadSanitizer: data race Write of size 8 at 0x000000000001 by thread T1: #0 isc_nmhandle_detach lib/isc/netmgr/netmgr.c:1258:15 #1 control_command bin/named/controlconf.c:388:3 #2 dispatch lib/isc/task.c:1152:7 #3 run lib/isc/task.c:1344:2 Previous read of size 8 at 0x000000000001 by thread T2: #0 isc_nm_pauseread lib/isc/netmgr/netmgr.c:1449:33 #1 recv_data lib/isccc/ccmsg.c:109:2 #2 isc__nm_tcp_shutdown lib/isc/netmgr/tcp.c:1157:4 #3 shutdown_walk_cb lib/isc/netmgr/netmgr.c:1515:3 #4 uv_walk <null> #5 process_queue lib/isc/netmgr/netmgr.c:659:4 #6 process_normal_queue lib/isc/netmgr/netmgr.c:582:10 #7 process_queues lib/isc/netmgr/netmgr.c:590:8 #8 async_cb lib/isc/netmgr/netmgr.c:548:2 #9 <null> <null>
This commit is contained in:
@@ -145,6 +145,11 @@ static void
|
||||
isc__nm_async_pausecb(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
static void
|
||||
isc__nm_async_resumecb(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
static void
|
||||
isc__nm_async_detach(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
|
||||
static void
|
||||
nmhandle_detach_cb(isc_nmhandle_t **handlep);
|
||||
|
||||
int
|
||||
isc_nm_tid(void) {
|
||||
@@ -655,6 +660,9 @@ process_queue(isc__networker_t *worker, isc_queue_t *queue) {
|
||||
case netievent_closecb:
|
||||
isc__nm_async_closecb(worker, ievent);
|
||||
break;
|
||||
case netievent_detach:
|
||||
isc__nm_async_detach(worker, ievent);
|
||||
break;
|
||||
case netievent_shutdown:
|
||||
isc__nm_async_shutdown(worker, ievent);
|
||||
break;
|
||||
@@ -1247,6 +1255,30 @@ isc_nmhandle_detach(isc_nmhandle_t **handlep) {
|
||||
handle = *handlep;
|
||||
*handlep = NULL;
|
||||
|
||||
sock = handle->sock;
|
||||
if (sock->tid == isc_nm_tid()) {
|
||||
nmhandle_detach_cb(&handle);
|
||||
} else {
|
||||
isc__netievent_detach_t *event =
|
||||
isc__nm_get_ievent(sock->mgr, netievent_detach);
|
||||
event->handle = handle; /* implict attach */
|
||||
isc__nmsocket_attach(sock, &event->sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nmhandle_detach_cb(isc_nmhandle_t **handlep) {
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_nmhandle_t *handle = NULL;
|
||||
|
||||
REQUIRE(handlep != NULL);
|
||||
REQUIRE(VALID_NMHANDLE(*handlep));
|
||||
|
||||
handle = *handlep;
|
||||
*handlep = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&handle->references) > 1) {
|
||||
return;
|
||||
}
|
||||
@@ -1506,6 +1538,20 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__nmsocket_detach(&ievent->sock);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_async_detach(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
isc__netievent_detach_t *ievent = (isc__netievent_detach_t *)ev0;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(ievent->sock));
|
||||
REQUIRE(ievent->sock->tid == isc_nm_tid());
|
||||
REQUIRE(ievent->handle != NULL);
|
||||
|
||||
UNUSED(worker);
|
||||
|
||||
isc__nmsocket_detach(&ievent->sock);
|
||||
nmhandle_detach_cb(&ievent->handle);
|
||||
}
|
||||
|
||||
static void
|
||||
shutdown_walk_cb(uv_handle_t *handle, void *arg) {
|
||||
UNUSED(arg);
|
||||
|
Reference in New Issue
Block a user