From 914a7e14e2af8260a1b0d797cc95e0552ccae53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 2 Feb 2022 10:50:27 +0100 Subject: [PATCH] Add network manager based timer API This commits adds API that allows to create arbitrary timers associated with the network manager handles. (cherry picked from commit 3c7b04d0150ae6d6192747d90d52247bd598bd9a) Conflict: UV_RUNTIME_CHECK to RUNTIME_CHECK Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/914a7e14e2af8260a1b0d797cc95e0552ccae53f --- lib/isc/include/isc/netmgr.h | 24 ++++++++++ lib/isc/netmgr/netmgr-int.h | 8 ++++ lib/isc/netmgr/netmgr.c | 91 ++++++++++++++++++++++++++++++++++++ lib/isc/win32/libisc.def.in | 5 ++ 4 files changed, 128 insertions(+) diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index 39dba1d376..7ec40e81b6 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -492,3 +492,27 @@ isc__nm_force_tid(int tid); void isc_nmhandle_setwritetimeout(isc_nmhandle_t *handle, uint64_t write_timeout); + +/* + * Timer related functions + */ + +typedef struct isc_nm_timer isc_nm_timer_t; + +typedef void (*isc_nm_timer_cb)(void *, isc_result_t); + +void +isc_nm_timer_create(isc_nmhandle_t *, isc_nm_timer_cb, void *, + isc_nm_timer_t **); + +void +isc_nm_timer_attach(isc_nm_timer_t *, isc_nm_timer_t **); + +void +isc_nm_timer_detach(isc_nm_timer_t **); + +void +isc_nm_timer_start(isc_nm_timer_t *, uint64_t); + +void +isc_nm_timer_stop(isc_nm_timer_t *); diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 3871d70939..23b197179a 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -350,6 +350,14 @@ struct isc__nm_uvreq { ISC_LINK(isc__nm_uvreq_t) link; }; +struct isc_nm_timer { + isc_refcount_t references; + uv_timer_t timer; + isc_nmhandle_t *handle; + isc_nm_timer_cb cb; + void *cbarg; +}; + void * isc__nm_get_netievent(isc_nm_t *mgr, isc__netievent_type type); /*%< diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 31917be101..fb9d77d3b4 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -3179,6 +3179,97 @@ isc_nm_work_offload(isc_nm_t *netmgr, isc_nm_workcb_t work_cb, RUNTIME_CHECK(r == 0); } +void +isc_nm_timer_create(isc_nmhandle_t *handle, isc_nm_timer_cb cb, void *cbarg, + isc_nm_timer_t **timerp) { + isc__networker_t *worker = NULL; + isc_nmsocket_t *sock = NULL; + isc_nm_timer_t *timer = NULL; + int r; + + REQUIRE(isc__nm_in_netthread()); + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(VALID_NMSOCK(handle->sock)); + + sock = handle->sock; + worker = &sock->mgr->workers[isc_nm_tid()]; + + timer = isc_mem_get(sock->mgr->mctx, sizeof(*timer)); + *timer = (isc_nm_timer_t){ .cb = cb, .cbarg = cbarg }; + isc_refcount_init(&timer->references, 1); + isc_nmhandle_attach(handle, &timer->handle); + + r = uv_timer_init(&worker->loop, &timer->timer); + UV_RUNTIME_CHECK(uv_timer_init, r); + + uv_handle_set_data((uv_handle_t *)&timer->timer, timer); + + *timerp = timer; +} + +void +isc_nm_timer_attach(isc_nm_timer_t *timer, isc_nm_timer_t **timerp) { + REQUIRE(timer != NULL); + REQUIRE(timerp != NULL && *timerp == NULL); + + isc_refcount_increment(&timer->references); + *timerp = timer; +} + +static void +timer_destroy(uv_handle_t *uvhandle) { + isc_nm_timer_t *timer = uv_handle_get_data(uvhandle); + isc_nmhandle_t *handle = timer->handle; + isc_mem_t *mctx = timer->handle->sock->mgr->mctx; + + isc_mem_put(mctx, timer, sizeof(*timer)); + + isc_nmhandle_detach(&handle); +} + +void +isc_nm_timer_detach(isc_nm_timer_t **timerp) { + isc_nm_timer_t *timer = NULL; + isc_nmhandle_t *handle = NULL; + + REQUIRE(timerp != NULL && *timerp != NULL); + + timer = *timerp; + *timerp = NULL; + + handle = timer->handle; + + REQUIRE(isc__nm_in_netthread()); + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(VALID_NMSOCK(handle->sock)); + + if (isc_refcount_decrement(&timer->references) == 1) { + uv_timer_stop(&timer->timer); + uv_close((uv_handle_t *)&timer->timer, timer_destroy); + } +} + +static void +timer_cb(uv_timer_t *uvtimer) { + isc_nm_timer_t *timer = uv_handle_get_data((uv_handle_t *)uvtimer); + + REQUIRE(timer->cb != NULL); + + timer->cb(timer->cbarg, ISC_R_TIMEDOUT); +} + +void +isc_nm_timer_start(isc_nm_timer_t *timer, uint64_t timeout) { + int r = uv_timer_start(&timer->timer, timer_cb, timeout, 0); + UV_RUNTIME_CHECK(uv_timer_start, r); +} + +void +isc_nm_timer_stop(isc_nm_timer_t *timer) { + int r = uv_timer_stop(&timer->timer); + UV_RUNTIME_CHECK(uv_timer_stop, r); +} + #ifdef NETMGR_TRACE /* * Dump all active sockets in netmgr. We output to stderr diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 79e7b64a58..ab7ad73d20 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -480,6 +480,11 @@ isc_nm_tcpconnect isc_nm_tcpdnsconnect isc_nm_tcpdns_sequential isc_nm_tid +isc_nm_timer_create +isc_nm_timer_attach +isc_nm_timer_detach +isc_nm_timer_start +isc_nm_timer_stop isc_nm_udpconnect isc_nm_work_offload isc_nmsocket_close -- 2.27.0