2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 16:15:27 +00:00

Use uv_idle API for calling asynchronous connect/read/send callback

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.
This commit is contained in:
Ondřej Surý
2023-03-24 10:36:58 +01:00
parent 670df3da74
commit 476198f26c
2 changed files with 48 additions and 31 deletions

View File

@@ -289,6 +289,7 @@ struct isc__nm_uvreq {
uv_connect_t connect; uv_connect_t connect;
uv_udp_send_t udp_send; uv_udp_send_t udp_send;
uv_fs_t fs; uv_fs_t fs;
uv_idle_t idle;
} uv_req; } uv_req;
ISC_LINK(isc__nm_uvreq_t) link; ISC_LINK(isc__nm_uvreq_t) link;
ISC_LINK(isc__nm_uvreq_t) inactive_link; ISC_LINK(isc__nm_uvreq_t) inactive_link;

View File

@@ -1594,7 +1594,6 @@ isc_nmhandle_netmgr(isc_nmhandle_t *handle) {
return (handle->sock->worker->netmgr); return (handle->sock->worker->netmgr);
} }
/* FIXME: Use per-worker mempool */
isc__nm_uvreq_t * isc__nm_uvreq_t *
isc___nm_uvreq_get(isc__networker_t *worker, isc_nmsocket_t *sock FLARG) { isc___nm_uvreq_get(isc__networker_t *worker, isc_nmsocket_t *sock FLARG) {
isc__nm_uvreq_t *req = NULL; isc__nm_uvreq_t *req = NULL;
@@ -1840,49 +1839,55 @@ isc__nmsocket_barrier_init(isc_nmsocket_t *listener) {
} }
static void static void
isc__nm_connectcb_job(void *arg) { isc__nm_uvreq_free(uv_handle_t *handle) {
isc__nm_uvreq_t *uvreq = arg; isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
isc_result_t eresult = uvreq->result;
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); 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 void
isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq, isc__nm_connectcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
isc_result_t eresult, bool async) { isc_result_t eresult, bool async) {
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
REQUIRE(VALID_UVREQ(uvreq)); REQUIRE(VALID_UVREQ(uvreq));
REQUIRE(VALID_NMHANDLE(uvreq->handle)); REQUIRE(VALID_NMHANDLE(uvreq->handle));
REQUIRE(uvreq->cb.connect != NULL);
uvreq->result = eresult;
if (!async) { if (!async) {
isc__nm_connectcb_job(uvreq); uvreq->cb.connect(uvreq->handle, eresult, uvreq->cbarg);
isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
return; return;
} }
isc_job_run(sock->worker->netmgr->loopmgr, isc__nm_connectcb_job, uvreq->result = eresult;
uvreq);
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 static void
isc__nm_readcb_job(void *arg) { isc___nm_readcb(uv_idle_t *handle) {
isc__nm_uvreq_t *uvreq = arg; isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
isc_result_t eresult = uvreq->result;
isc_nmsocket_t *sock = uvreq->handle->sock;
isc_region_t region; isc_region_t region;
region.base = (unsigned char *)uvreq->uvbuf.base; region.base = (unsigned char *)uvreq->uvbuf.base;
region.length = uvreq->uvbuf.len; 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 void
@@ -1891,25 +1896,33 @@ isc__nm_readcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
REQUIRE(VALID_UVREQ(uvreq)); REQUIRE(VALID_UVREQ(uvreq));
REQUIRE(VALID_NMHANDLE(uvreq->handle)); REQUIRE(VALID_NMHANDLE(uvreq->handle));
uvreq->result = eresult;
if (!async) { 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; 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 static void
isc__nm_sendcb_job(void *arg) { isc___nm_sendcb(uv_idle_t *handle) {
isc__nm_uvreq_t *uvreq = arg; isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
isc_result_t eresult = uvreq->result;
isc_nmsocket_t *sock = uvreq->handle->sock;
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 void
@@ -1921,11 +1934,14 @@ isc__nm_sendcb(isc_nmsocket_t *sock, isc__nm_uvreq_t *uvreq,
uvreq->result = eresult; uvreq->result = eresult;
if (!async) { 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; 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 static void