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:
@@ -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;
|
||||||
|
@@ -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, ®ion, uvreq->cbarg);
|
uvreq->cb.recv(uvreq->handle, uvreq->result, ®ion, 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, ®ion, 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
|
||||||
|
Reference in New Issue
Block a user