]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add isc__nm_async_run()
authorArtem Boldariev <artem@isc.org>
Fri, 6 Sep 2024 14:28:58 +0000 (17:28 +0300)
committerAndoni Duarte Pintado <andoni@isc.org>
Wed, 15 Jan 2025 15:43:47 +0000 (16:43 +0100)
This commit adds isc__nm_async_run() which is very similar to
isc_async_run() in newer versions of BIND: it allows calling a
callback asynchronously.

Potentially, it can be used to replace some other async operations in
other networking code, in particular the delayed I/O calls in TLS a
TCP DNS transports to name a few and remove quiet a lot of code, but
it we are unlikely to do that for the strictly maintenance only
branch, so it is protected with DoH-related #ifdefs.

It is implemented in a "universal" way mainly because doing it in the
specific code requires the same amount of code and is not simpler.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c

index d3c790a85758534f82f5ee7bf55717d73f77db45..f80fe9c1df2ab10b94b231bc60168de5bc96bfb1 100644 (file)
@@ -338,6 +338,7 @@ typedef enum isc__netievent_type {
        netievent_privilegedtask,
 
        netievent_settlsctx,
+       netievent_asyncrun,
 
        /*
         * event type values higher than this will be treated
@@ -709,6 +710,42 @@ typedef struct isc__netievent__tlsctx {
        }
 
 #ifdef HAVE_LIBNGHTTP2
+typedef void (*isc__nm_asyncrun_cb_t)(void *);
+
+typedef struct isc__netievent__asyncrun {
+       isc__netievent_type type;
+       ISC_LINK(isc__netievent_t) link;
+       isc__nm_asyncrun_cb_t cb;
+       void *cbarg;
+} isc__netievent__asyncrun_t;
+
+#define NETIEVENT_ASYNCRUN_TYPE(type) \
+       typedef isc__netievent__asyncrun_t isc__netievent_##type##_t;
+
+#define NETIEVENT_ASYNCRUN_DECL(type)                                 \
+       isc__netievent_##type##_t *isc__nm_get_netievent_##type(      \
+               isc_nm_t *nm, isc__nm_asyncrun_cb_t cb, void *cbarg); \
+       void isc__nm_put_netievent_##type(isc_nm_t *nm,               \
+                                         isc__netievent_##type##_t *ievent);
+
+#define NETIEVENT_ASYNCRUN_DEF(type)                                           \
+       isc__netievent_##type##_t *isc__nm_get_netievent_##type(               \
+               isc_nm_t *nm, isc__nm_asyncrun_cb_t cb, void *cbarg) {         \
+               isc__netievent_##type##_t *ievent =                            \
+                       isc__nm_get_netievent(nm, netievent_##type);           \
+               ievent->cb = cb;                                               \
+               ievent->cbarg = cbarg;                                         \
+                                                                               \
+               return (ievent);                                               \
+       }                                                                      \
+                                                                               \
+       void isc__nm_put_netievent_##type(isc_nm_t *nm,                        \
+                                         isc__netievent_##type##_t *ievent) { \
+               ievent->cb = NULL;                                             \
+               ievent->cbarg = NULL;                                          \
+               isc__nm_put_netievent(nm, ievent);                             \
+       }
+
 typedef struct isc__netievent__http_eps {
        NETIEVENT__SOCKET;
        isc_nm_http_endpoints_t *endpoints;
@@ -753,6 +790,7 @@ typedef union {
        isc__netievent_tlsconnect_t nitc;
        isc__netievent__tlsctx_t nitls;
 #ifdef HAVE_LIBNGHTTP2
+       isc__netievent__asyncrun_t niasync;
        isc__netievent__http_eps_t nihttpeps;
 #endif /* HAVE_LIBNGHTTP2 */
 } isc__netievent_storage_t;
@@ -1914,7 +1952,10 @@ void
 isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
                             const uint32_t max_concurrent_streams);
 
-#endif
+void
+isc__nm_async_asyncrun(isc__networker_t *worker, isc__netievent_t *ev0);
+
+#endif /* HAVE_LIBNGHTTP2 */
 
 void
 isc__nm_async_settlsctx(isc__networker_t *worker, isc__netievent_t *ev0);
@@ -2104,6 +2145,8 @@ NETIEVENT_SOCKET_TYPE(tlsdnscycle);
 NETIEVENT_SOCKET_REQ_TYPE(httpsend);
 NETIEVENT_SOCKET_TYPE(httpclose);
 NETIEVENT_SOCKET_HTTP_EPS_TYPE(httpendpoints);
+
+NETIEVENT_ASYNCRUN_TYPE(asyncrun);
 #endif /* HAVE_LIBNGHTTP2 */
 
 NETIEVENT_SOCKET_REQ_TYPE(tcpconnect);
@@ -2178,6 +2221,8 @@ NETIEVENT_SOCKET_DECL(tlsdnscycle);
 NETIEVENT_SOCKET_REQ_DECL(httpsend);
 NETIEVENT_SOCKET_DECL(httpclose);
 NETIEVENT_SOCKET_HTTP_EPS_DECL(httpendpoints);
+
+NETIEVENT_ASYNCRUN_DECL(asyncrun);
 #endif /* HAVE_LIBNGHTTP2 */
 
 NETIEVENT_SOCKET_REQ_DECL(tcpconnect);
@@ -2301,3 +2346,13 @@ 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.
  */
+
+#if HAVE_LIBNGHTTP2
+void
+isc__nm_async_run(isc__networker_t *worker, isc__nm_asyncrun_cb_t cb,
+                 void *cbarg);
+/*
+ * Call the given callback asynchronously by the give network manager
+ * worker, pass the given argument to it.
+ */
+#endif /* HAVE_LIBNGHTTP2 */
index bc56d7a2eab4b2698143411f37dc8107d521c734..d9a5a07ef4644b78fd3a977a461bdbb346977707 100644 (file)
@@ -998,6 +998,8 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) {
                NETIEVENT_CASE(httpsend);
                NETIEVENT_CASE(httpclose);
                NETIEVENT_CASE(httpendpoints);
+
+               NETIEVENT_CASE(asyncrun);
 #endif
                NETIEVENT_CASE(settlsctx);
                NETIEVENT_CASE(sockstop);
@@ -1116,6 +1118,8 @@ NETIEVENT_SOCKET_DEF(tlsdnsshutdown);
 NETIEVENT_SOCKET_REQ_DEF(httpsend);
 NETIEVENT_SOCKET_DEF(httpclose);
 NETIEVENT_SOCKET_HTTP_EPS_DEF(httpendpoints);
+
+NETIEVENT_ASYNCRUN_DEF(asyncrun);
 #endif /* HAVE_LIBNGHTTP2 */
 
 NETIEVENT_SOCKET_REQ_DEF(tcpconnect);
@@ -3983,6 +3987,29 @@ isc__nmhandle_set_manual_timer(isc_nmhandle_t *handle, const bool manual) {
        UNREACHABLE();
 }
 
+#if HAVE_LIBNGHTTP2
+void
+isc__nm_async_run(isc__networker_t *worker, isc__nm_asyncrun_cb_t cb,
+                 void *cbarg) {
+       isc__netievent__asyncrun_t *ievent = NULL;
+       REQUIRE(worker != NULL);
+       REQUIRE(cb != NULL);
+
+       ievent = isc__nm_get_netievent_asyncrun(worker->mgr, cb, cbarg);
+       isc__nm_enqueue_ievent(worker, (isc__netievent_t *)ievent);
+}
+
+void
+isc__nm_async_asyncrun(isc__networker_t *worker, isc__netievent_t *ev0) {
+       isc__netievent_asyncrun_t *ievent = (isc__netievent_asyncrun_t *)ev0;
+
+       UNUSED(worker);
+
+       ievent->cb(ievent->cbarg);
+}
+
+#endif /* HAVE_LIBNGHTTP2 */
+
 #ifdef NETMGR_TRACE
 /*
  * Dump all active sockets in netmgr. We output to stderr