bind/backport-0022-Add-network-manager-based-timer-API.patch

189 lines
5.2 KiB
Diff
Raw Normal View History

2022-12-26 15:55:21 +08:00
From 914a7e14e2af8260a1b0d797cc95e0552ccae53f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
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