From f3004da3a5ce577c0e794606fd32f1b99d830525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 24 Nov 2022 17:11:22 +0100 Subject: [PATCH] Make the netmgr send callback to be asynchronous only when needed Previously, the send callback would be synchronous only on success. Add an option (similar to what other callbacks have) to decide whether we need the asynchronous send callback on a higher level. On a general level, we need the asynchronous callbacks to happen only when we are invoking the callback from the public API. If the path to the callback went through the libuv callback or netmgr callback, we are already on asynchronous path, and there's no need to make the call to the callback asynchronous again. For the send callback, this means we need the asynchronous path for failure paths inside the isc_nm_send() (which calls isc__nm_udp_send(), isc__nm_tcp_send(), etc...) - all other invocations of the send callback could be synchronous, because those are called from the respective libuv send callbacks. --- lib/isc/netmgr/netmgr-int.h | 2 +- lib/isc/netmgr/netmgr.c | 4 ++-- lib/isc/netmgr/tcp.c | 5 +++-- lib/isc/netmgr/tcpdns.c | 5 +++-- lib/isc/netmgr/tlsdns.c | 2 +- lib/isc/netmgr/udp.c | 6 ++++-- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index d17c18d81b..4271990bff 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -1946,7 +1946,7 @@ isc__nm_alloc_dnsbuf(isc_nmsocket_t *sock, size_t len); void isc__nm_failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req, - isc_result_t eresult); + isc_result_t eresult, bool async); void isc__nm_failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult); void diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 7583e531f5..f2b4127cf2 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -1324,12 +1324,12 @@ isc__nm_alloc_dnsbuf(isc_nmsocket_t *sock, size_t len) { void isc__nm_failed_send_cb(isc_nmsocket_t *sock, isc__nm_uvreq_t *req, - isc_result_t eresult) { + isc_result_t eresult, bool async) { REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_UVREQ(req)); if (req->cb.send != NULL) { - isc__nm_sendcb(sock, req, eresult, true); + isc__nm_sendcb(sock, req, eresult, async); } else { isc__nm_uvreq_put(&req, sock); } diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 9b2e938003..239a24fb5a 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -1029,7 +1029,7 @@ isc__nm_tcp_send(isc_nmhandle_t *handle, const isc_region_t *region, result = tcp_send_direct(sock, uvreq); if (result != ISC_R_SUCCESS) { isc__nm_incstats(sock, STATID_SENDFAIL); - isc__nm_failed_send_cb(sock, uvreq, result); + isc__nm_failed_send_cb(sock, uvreq, result, true); } return; @@ -1050,7 +1050,8 @@ tcp_send_cb(uv_write_t *req, int status) { if (status < 0) { isc__nm_incstats(sock, STATID_SENDFAIL); - isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(status)); + isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(status), + false); return; } diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index e1016bea49..e5f3178ace 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -1147,7 +1147,8 @@ tcpdns_send_cb(uv_write_t *req, int status) { if (status < 0) { isc__nm_incstats(sock, STATID_SENDFAIL); - isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(status)); + isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(status), + false); return; } @@ -1233,7 +1234,7 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) { return; fail: isc__nm_incstats(sock, STATID_SENDFAIL); - isc__nm_failed_send_cb(sock, uvreq, result); + isc__nm_failed_send_cb(sock, uvreq, result, true); } static void diff --git a/lib/isc/netmgr/tlsdns.c b/lib/isc/netmgr/tlsdns.c index 528e6d442b..536aa2a7f4 100644 --- a/lib/isc/netmgr/tlsdns.c +++ b/lib/isc/netmgr/tlsdns.c @@ -1794,7 +1794,7 @@ isc__nm_async_tlsdnssend(isc__networker_t *worker, isc__netievent_t *ev0) { result = tlsdns_send_direct(sock, uvreq); if (result != ISC_R_SUCCESS) { isc__nm_incstats(sock, STATID_SENDFAIL); - isc__nm_failed_send_cb(sock, uvreq, result); + isc__nm_failed_send_cb(sock, uvreq, result, false); } } diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 0c5d4cf07d..6b7ae0810c 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -663,8 +663,10 @@ udp_send_cb(uv_udp_send_t *req, int status) { REQUIRE(sock->tid == isc_tid()); if (status < 0) { - result = isc_uverr2result(status); isc__nm_incstats(sock, STATID_SENDFAIL); + isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(status), + false); + return; } isc__nm_sendcb(sock, uvreq, result, false); @@ -744,7 +746,7 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region, } return; fail: - isc__nm_failed_send_cb(sock, uvreq, result); + isc__nm_failed_send_cb(sock, uvreq, result, true); } static isc_result_t