]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add network manager based timer API
authorOndřej Surý <ondrej@isc.org>
Wed, 2 Feb 2022 09:50:27 +0000 (10:50 +0100)
committerOndřej Surý <ondrej@isc.org>
Thu, 17 Feb 2022 21:59:24 +0000 (22:59 +0100)
This commits adds API that allows to create arbitrary timers associated
with the network manager handles.

(cherry picked from commit 3c7b04d0150ae6d6192747d90d52247bd598bd9a)

lib/isc/include/isc/netmgr.h
lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/win32/libisc.def.in

index 39dba1d376daf38390ee2433ff7beb3bb9a96a24..7ec40e81b6f0a9421f748f5aa6e7dfea029af6f8 100644 (file)
@@ -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 *);
index 3871d70939d7527e9c5b3254905fce957cc088c5..23b197179a3a9fb0c9e5314e69600296e7e9ebac 100644 (file)
@@ -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);
 /*%<
index 31917be101451481f7dee45c3e2845505a78a16b..fb9d77d3b494869a2dfdf4bf5606e885270ef0c5 100644 (file)
@@ -3179,6 +3179,97 @@ isc_nm_work_offload(isc_nm_t *netmgr, isc_nm_workcb_t work_cb,
        UV_RUNTIME_CHECK(uv_queue_work, r);
 }
 
+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
index 79e7b64a58642848236ac0088ab039db3449c629..ab7ad73d202ec5bbfff914a76d175900f0286ed2 100644 (file)
@@ -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