From: Ondřej Surý Date: Tue, 27 Sep 2022 13:20:33 +0000 (+0200) Subject: Call the isc__nm_udp_send() callbacks asynchronously on shutdown X-Git-Tag: v9.19.6~23^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=173c3524520b28f966e2d80cf98338befb13a708;p=thirdparty%2Fbind9.git Call the isc__nm_udp_send() callbacks asynchronously on shutdown The isc__nm_udp_send() callback would be called synchronously when shutting down or when the socket has been closed. This could lead to double locking in the calling code and thus those callbacks needs to be called asynchronously. --- diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 9b715d9b6ce..587e368203d 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -685,6 +685,7 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region, isc__networker_t *worker = NULL; uint32_t maxudp; int r; + isc_result_t result; REQUIRE(VALID_NMSOCK(sock)); REQUIRE(sock->type == isc_nm_udpsocket); @@ -706,16 +707,6 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region, return; } - if (isc__nm_closing(worker)) { - cb(handle, ISC_R_SHUTTINGDOWN, cbarg); - return; - } - - if (isc__nmsocket_closing(sock)) { - cb(handle, ISC_R_CANCELED, cbarg); - return; - } - uvreq = isc__nm_uvreq_get(sock->worker, sock); uvreq->uvbuf.base = (char *)region->base; uvreq->uvbuf.len = region->length; @@ -725,6 +716,16 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region, uvreq->cb.send = cb; uvreq->cbarg = cbarg; + if (isc__nm_closing(worker)) { + result = ISC_R_SHUTTINGDOWN; + goto fail; + } + + if (isc__nmsocket_closing(sock)) { + result = ISC_R_CANCELED; + goto fail; + } + /* * We used uv_udp_connect(), so the peer address has to be * set to NULL or else uv_udp_send() could fail or assert, @@ -738,8 +739,12 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region, &uvreq->uvbuf, 1, sa, udp_send_cb); if (r < 0) { isc__nm_incstats(sock, STATID_SENDFAIL); - isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(r)); + result = isc_uverr2result(r); + goto fail; } + return; +fail: + isc__nm_failed_send_cb(sock, uvreq, result); } static isc_result_t