From: Artem Boldariev Date: Tue, 18 Oct 2022 12:21:10 +0000 (+0300) Subject: TCP: add manual read timer control mode X-Git-Tag: v9.19.9~68^2~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9aabd55725bad59ac33befe49a10a0fd371b1e83;p=thirdparty%2Fbind9.git TCP: add manual read timer control mode This commit adds a manual read timer control mode to the TCP code (adding isc__nmhandle_set_manual_timer() as the interface to it). Manual read timer control mode suppresses read timer restarting the read timer when receiving any amount of data. This way the read timer can be controlled manually using: * isc__nmsocket_timer_start(); * isc__nmsocket_timer_stop(); * isc__nmsocket_timer_restart(). The change is required to make it possible to implement more sophisticated read timer control policies in DNS transports, built on top of TCP. --- diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index c23a53731ae..18833bfbde2 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -1062,6 +1062,7 @@ struct isc_nmsocket { atomic_int_fast32_t active_child_connections; bool barrier_initialised; + bool manual_read_timer; #ifdef NETMGR_TRACE void *backtrace[TRACE_SIZE]; int backtrace_size; @@ -1354,6 +1355,9 @@ isc__nm_tcp_settimeout(isc_nmhandle_t *handle, uint32_t timeout); * Set the read timeout for the TCP socket associated with 'handle'. */ +void +isc__nmhandle_tcp_set_manual_timer(isc_nmhandle_t *handle, const bool manual); + void isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0); void @@ -2008,3 +2012,10 @@ isc__nmsocket_log(const isc_nmsocket_t *sock, int level, const char *fmt, ...) void isc__nmhandle_log(const isc_nmhandle_t *handle, int level, const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); + +void +isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual); +/* + * Set manual read timer control mode - so that it will not get reset + * automatically on read nor get started when read is initiated. + */ diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index fa9f60ec18a..350e3ba9639 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -2898,6 +2898,25 @@ isc__nmhandle_log(const isc_nmhandle_t *handle, int level, const char *fmt, isc__nmsocket_log(handle->sock, level, "handle %p: %s", handle, msgbuf); } +void +isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual) { + isc_nmsocket_t *sock; + + REQUIRE(VALID_NMHANDLE(handle)); + sock = handle->sock; + REQUIRE(VALID_NMSOCK(sock)); + + switch (sock->type) { + case isc_nm_tcpsocket: + isc__nmhandle_tcp_set_manual_timer(handle, manual); + return; + default: + break; + }; + + UNREACHABLE(); +} + #ifdef NETMGR_TRACE /* * Dump all active sockets in netmgr. We output to stderr diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 52e5abac16b..c994622d0c5 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -762,7 +762,9 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { goto failure; } - isc__nmsocket_timer_start(sock); + if (!sock->manual_read_timer) { + isc__nmsocket_timer_start(sock); + } return; failure: @@ -831,7 +833,7 @@ isc__nm_tcp_read_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { isc__nm_readcb(sock, req, ISC_R_SUCCESS, false); /* The readcb could have paused the reading */ - if (sock->reading) { + if (sock->reading && !sock->manual_read_timer) { /* The timer will be updated */ isc__nmsocket_timer_restart(sock); } @@ -1225,3 +1227,18 @@ isc__nm_tcp_shutdown(isc_nmsocket_t *sock) { isc__nmsocket_prep_destroy(sock); } } + +void +isc__nmhandle_tcp_set_manual_timer(isc_nmhandle_t *handle, const bool manual) { + isc_nmsocket_t *sock; + + REQUIRE(VALID_NMHANDLE(handle)); + sock = handle->sock; + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpsocket); + REQUIRE(sock->tid == isc_tid()); + REQUIRE(!sock->reading); + REQUIRE(!sock->recv_read); + + sock->manual_read_timer = manual; +}