2
0
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:
Mark Andrews
2020-10-12 17:51:09 +11:00
parent 8c4cf5d2e5
commit f95ba8aa20
2 changed files with 49 additions and 0 deletions

View File

@@ -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);