From: Ondřej Surý Date: Fri, 2 Oct 2020 07:28:29 +0000 (+0200) Subject: Change the isc__nm_tcpdns_stoplistening() to be asynchronous event X-Git-Tag: v9.17.6~5^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d86a74d8a4c1c530baa714bbbad78fba9a4b29ab;p=thirdparty%2Fbind9.git Change the isc__nm_tcpdns_stoplistening() to be asynchronous event The isc__nm_tcpdns_stoplistening() would call isc__nmsocket_clearcb() that would clear the .accept_cb from non-netmgr thread. Change the tcpdns_stoplistening to enqueue ievent that would get processed in the right netmgr thread to avoid locking. --- diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index ceeb5cbb276..4d6ef881930 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -149,6 +149,7 @@ typedef enum isc__netievent_type { netievent_tcpdnssend, netievent_tcpdnsclose, + netievent_tcpdnsstop, netievent_closecb, netievent_shutdown, @@ -217,6 +218,7 @@ typedef isc__netievent__socket_t isc__netievent_startread_t; typedef isc__netievent__socket_t isc__netievent_pauseread_t; typedef isc__netievent__socket_t isc__netievent_closecb_t; typedef isc__netievent__socket_t isc__netievent_tcpdnsclose_t; +typedef isc__netievent__socket_t isc__netievent_tcpdnsstop_t; typedef struct isc__netievent__socket_req { isc__netievent_type type; @@ -787,9 +789,10 @@ isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock); void isc__nm_async_tcpdnsclose(isc__networker_t *worker, isc__netievent_t *ev0); - void isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0); +void +isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0); #define isc__nm_uverr2result(x) \ isc___nm_uverr2result(x, true, __FILE__, __LINE__) diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 28dc6f22e11..6ee8bb72885 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -648,6 +648,9 @@ process_queue(isc__networker_t *worker, isc_queue_t *queue) { case netievent_tcpdnsclose: isc__nm_async_tcpdnsclose(worker, ievent); break; + case netievent_tcpdnsstop: + isc__nm_async_tcpdnsstop(worker, ievent); + break; case netievent_closecb: isc__nm_async_closecb(worker, ievent); diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 5f731ddfee8..cb7331d342f 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -536,12 +536,11 @@ error: void isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) { - isc__netievent_tcpstop_t *ievent = NULL; - REQUIRE(VALID_NMSOCK(sock)); - REQUIRE(!isc__nm_in_netthread()); + REQUIRE(sock->type == isc_nm_tcplistener); - ievent = isc__nm_get_ievent(sock->mgr, netievent_tcpstop); + isc__netievent_tcpstop_t *ievent = + isc__nm_get_ievent(sock->mgr, netievent_tcpstop); isc__nmsocket_attach(sock, &ievent->sock); isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], (isc__netievent_t *)ievent); diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index 4e20be080f0..8060bbfe9a4 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -392,18 +392,40 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb, } void -isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) { +isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) { + isc__netievent_tcpstop_t *ievent = (isc__netievent_tcpdnsstop_t *)ev0; + isc_nmsocket_t *sock = ievent->sock; + + UNUSED(worker); + + REQUIRE(isc__nm_in_netthread()); REQUIRE(VALID_NMSOCK(sock)); REQUIRE(sock->type == isc_nm_tcpdnslistener); + REQUIRE(sock->tid == isc_nm_tid()); atomic_store(&sock->listening, false); atomic_store(&sock->closed, true); + isc__nmsocket_clearcb(sock); if (sock->outer != NULL) { isc__nm_tcp_stoplistening(sock->outer); isc__nmsocket_detach(&sock->outer); } + + isc__nmsocket_detach(&sock); +} + +void +isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpdnslistener); + + isc__netievent_tcpdnsstop_t *ievent = + isc__nm_get_ievent(sock->mgr, netievent_tcpdnsstop); + isc__nmsocket_attach(sock, &ievent->sock); + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); } void