mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Merge branch '3534-make-the-isc_nm_udp_send-on-shutdown-callback-asynchronous' into 'main'
Call the isc__nm_udp_send() callbacks asynchronously on shutdown Closes #3534 See merge request isc-projects/bind9!6828
This commit is contained in:
commit
05d60071a7
2 changed files with 26 additions and 11 deletions
|
|
@ -104,3 +104,13 @@ functions MUST be called from the thread that created the network manager
|
|||
socket.
|
||||
|
||||
The ``isc_nm_listen*()`` functions MUST be called from the ``main`` loop.
|
||||
|
||||
The general design of Network Manager is based on callbacks. An extra care must
|
||||
be taken when implementing new functions because the callbacks MUST be called
|
||||
asynchronously because the caller might be inside a lock and the same lock must
|
||||
be acquired in the callback. This doesn't mean that the callback must be always
|
||||
called asynchronously, because sometimes we are already in the libuv callback
|
||||
and thus we can just call the callback directly, but in other places, especially
|
||||
when returning an error, the control hasn't been returned to the caller yet and
|
||||
in such case, the callback must be scheduled onto the event loop instead of
|
||||
executing it directly.
|
||||
|
|
|
|||
|
|
@ -685,6 +685,7 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
|||
isc__networker_t *worker = NULL;
|
||||
uint32_t maxudp;
|
||||
int r;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
|
|
@ -706,16 +707,6 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
|||
return;
|
||||
}
|
||||
|
||||
if (isc__nm_closing(worker)) {
|
||||
cb(handle, ISC_R_SHUTTINGDOWN, cbarg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
cb(handle, ISC_R_CANCELED, cbarg);
|
||||
return;
|
||||
}
|
||||
|
||||
uvreq = isc__nm_uvreq_get(sock->worker, sock);
|
||||
uvreq->uvbuf.base = (char *)region->base;
|
||||
uvreq->uvbuf.len = region->length;
|
||||
|
|
@ -725,6 +716,16 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
|||
uvreq->cb.send = cb;
|
||||
uvreq->cbarg = cbarg;
|
||||
|
||||
if (isc__nm_closing(worker)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (isc__nmsocket_closing(sock)) {
|
||||
result = ISC_R_CANCELED;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* We used uv_udp_connect(), so the peer address has to be
|
||||
* set to NULL or else uv_udp_send() could fail or assert,
|
||||
|
|
@ -738,8 +739,12 @@ isc__nm_udp_send(isc_nmhandle_t *handle, const isc_region_t *region,
|
|||
&uvreq->uvbuf, 1, sa, udp_send_cb);
|
||||
if (r < 0) {
|
||||
isc__nm_incstats(sock, STATID_SENDFAIL);
|
||||
isc__nm_failed_send_cb(sock, uvreq, isc_uverr2result(r));
|
||||
result = isc_uverr2result(r);
|
||||
goto fail;
|
||||
}
|
||||
return;
|
||||
fail:
|
||||
isc__nm_failed_send_cb(sock, uvreq, result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
|
|||
Loading…
Reference in a new issue