]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use uv_idle API for calling asynchronous connect/read/send callback
authorOndřej Surý <ondrej@isc.org>
Fri, 24 Mar 2023 09:36:58 +0000 (10:36 +0100)
committerOndřej Surý <ondrej@isc.org>
Wed, 29 Mar 2023 19:16:44 +0000 (21:16 +0200)
Instead of using isc_job_run() that's quite heavy as it allocates memory
for every new job, add uv_idle_t to uvreq union, and use uv_idle API
directly to execute the connect/read/send callback without any
additional allocations.

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

index 095baf09b0ebd593a5c2f3efd2fe71fae085ba33..30c74687b3b74bb94883c67e0ff7ea740184ba83 100644 (file)
@@ -289,6 +289,7 @@ struct isc__nm_uvreq {
                uv_connect_t connect;
                uv_udp_send_t udp_send;
                uv_fs_t fs;
+               uv_idle_t idle;
        } uv_req;
        ISC_LINK(isc__nm_uvreq_t) link;
        ISC_LINK(isc__nm_uvreq_t) inactive_link;
index bdc5905aeb09aa86f2721bfe806ec946d7a09432..b34e2348c0a2a5483ec1ffb943ad200c687ebac5 100644 (file)
@@ -1594,7 +1594,6 @@ isc_nmhandle_netmgr(isc_nmhandle_t *handle) {
        return (handle->sock->worker->netmgr);
 }
 
-/* FIXME: Use per-worker mempool */
 isc__nm_uvreq_t *
 isc___nm_uvreq_get(isc__networker_t *worker, isc_nmsocket_t *sock FLARG) {
        isc__nm_uvreq_t *req = NULL;
@@ -1840,49 +1839,55 @@ isc__nmsocket_barrier_init(isc_nmsocket_t *listener) {
 }
 
 static void
-isc__nm_connectcb_job(void *arg) {
-       isc__nm_uvreq_t *uvreq = arg;
-       isc_result_t eresult = uvreq->result;
+isc__nm_uvreq_free(uv_handle_t *handle) {
+       isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
 
-       REQUIRE(VALID_UVREQ(uvreq));
-       REQUIRE(VALID_NMHANDLE(uvreq->handle));
-       REQUIRE(uvreq->cb.connect != NULL);
-
-       uvreq->cb.connect(uvreq->handle, eresult, uvreq->cbarg);
        isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
 }
 
+static void
+isc___nm_connectcb(uv_idle_t *handle) {
+       isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
+
+       uvreq->cb.connect(uvreq->handle, uvreq->result, uvreq->cbarg);
+
+       uv_idle_stop(handle);
+       uv_close(handle, isc__nm_uvreq_free);
+}
+
 void
 isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
                  isc_result_t eresult, bool async) {
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(VALID_UVREQ(uvreq));
        REQUIRE(VALID_NMHANDLE(uvreq->handle));
-
-       uvreq->result = eresult;
+       REQUIRE(uvreq->cb.connect != NULL);
 
        if (!async) {
-               isc__nm_connectcb_job(uvreq);
+               uvreq->cb.connect(uvreq->handle, eresult, uvreq->cbarg);
+               isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
                return;
        }
 
-       isc_job_run(sock->worker->netmgr->loopmgr, isc__nm_connectcb_job,
-                   uvreq);
+       uvreq->result = eresult;
+
+       uv_idle_init(&sock->worker->loop->loop, &uvreq->uv_req.idle);
+       uv_idle_start(&uvreq->uv_req.idle, isc___nm_connectcb);
+       uv_handle_set_data(&uvreq->uv_req.idle, uvreq);
 }
 
 static void
-isc__nm_readcb_job(void *arg) {
-       isc__nm_uvreq_t *uvreq = arg;
-       isc_result_t eresult = uvreq->result;
-       isc_nmsocket_t *sock = uvreq->handle->sock;
+isc___nm_readcb(uv_idle_t *handle) {
+       isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
        isc_region_t region;
 
        region.base = (unsigned char *)uvreq->uvbuf.base;
        region.length = uvreq->uvbuf.len;
 
-       uvreq->cb.recv(uvreq->handle, eresult, &region, uvreq->cbarg);
+       uvreq->cb.recv(uvreq->handle, uvreq->result, &region, uvreq->cbarg);
 
-       isc__nm_uvreq_put(&uvreq, sock);
+       uv_idle_stop(handle);
+       uv_close(handle, isc__nm_uvreq_free);
 }
 
 void
@@ -1891,25 +1896,33 @@ isc__nm_readcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(VALID_UVREQ(uvreq));
        REQUIRE(VALID_NMHANDLE(uvreq->handle));
-       uvreq->result = eresult;
 
        if (!async) {
-               isc__nm_readcb_job(uvreq);
+               isc_region_t region;
+
+               region.base = (unsigned char *)uvreq->uvbuf.base;
+               region.length = uvreq->uvbuf.len;
+
+               uvreq->cb.recv(uvreq->handle, eresult, &region, uvreq->cbarg);
+               isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
                return;
        }
 
-       isc_job_run(sock->worker->netmgr->loopmgr, isc__nm_readcb_job, uvreq);
+       uvreq->result = eresult;
+
+       uv_idle_init(&sock->worker->loop->loop, &uvreq->uv_req.idle);
+       uv_idle_start(&uvreq->uv_req.idle, isc___nm_readcb);
+       uv_handle_set_data(&uvreq->uv_req.idle, uvreq);
 }
 
 static void
-isc__nm_sendcb_job(void *arg) {
-       isc__nm_uvreq_t *uvreq = arg;
-       isc_result_t eresult = uvreq->result;
-       isc_nmsocket_t *sock = uvreq->handle->sock;
+isc___nm_sendcb(uv_idle_t *handle) {
+       isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
 
-       uvreq->cb.send(uvreq->handle, eresult, uvreq->cbarg);
+       uvreq->cb.send(uvreq->handle, uvreq->result, uvreq->cbarg);
 
-       isc__nm_uvreq_put(&uvreq, sock);
+       uv_idle_stop(handle);
+       uv_close(handle, isc__nm_uvreq_free);
 }
 
 void
@@ -1921,11 +1934,14 @@ isc__nm_sendcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
        uvreq->result = eresult;
 
        if (!async) {
-               isc__nm_sendcb_job(uvreq);
+               uvreq->cb.send(uvreq->handle, uvreq->result, uvreq->cbarg);
+               isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
                return;
        }
 
-       isc_job_run(sock->worker->netmgr->loopmgr, isc__nm_sendcb_job, uvreq);
+       uv_idle_init(&sock->worker->loop->loop, &uvreq->uv_req.idle);
+       uv_idle_start(&uvreq->uv_req.idle, isc___nm_sendcb);
+       uv_handle_set_data(&uvreq->uv_req.idle, uvreq);
 }
 
 static void