netmgr: fix a non-thread-safe access to libuv structures
In tcp and udp stoplistening code we accessed libuv structures from a different thread, which caused a shutdown crash when named was under load. Also added additional DbC checks making sure we're in a proper thread when accessing uv_ functions.
This commit is contained in:
@@ -606,8 +606,8 @@ isc__nmsocket_prep_destroy(isc_nmsocket_t *sock);
|
||||
bool
|
||||
isc__nmsocket_active(isc_nmsocket_t *sock);
|
||||
/*%<
|
||||
* Check is socket 'sock' is active - by checking either sock->active or
|
||||
* sock->parent->active;
|
||||
* Determine whether 'sock' is active by checking 'sock->active'
|
||||
* or, for child sockets, 'sock->parent->active'.
|
||||
*/
|
||||
|
||||
void
|
||||
|
||||
@@ -419,7 +419,7 @@ stoplistening(isc_nmsocket_t *sock) {
|
||||
event = isc__nm_get_ievent(sock->mgr, netievent_tcpchildstop);
|
||||
isc_nmsocket_attach(&sock->children[i], &event->sock);
|
||||
|
||||
if (i == sock->tid) {
|
||||
if (isc_nm_tid() == sock->children[i].tid) {
|
||||
isc__nm_async_tcpchildstop(&sock->mgr->workers[i],
|
||||
(isc__netievent_t *) event);
|
||||
isc__nm_put_ievent(sock->mgr, event);
|
||||
|
||||
@@ -122,6 +122,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->iface != NULL);
|
||||
REQUIRE(sock->parent != NULL);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
uv_udp_init(&worker->loop, &sock->uv_handle.udp);
|
||||
uv_handle_set_data(&sock->uv_handle.handle, NULL);
|
||||
@@ -164,7 +165,8 @@ udp_close_cb(uv_handle_t *handle) {
|
||||
|
||||
static void
|
||||
stop_udp_child(isc_nmsocket_t *sock) {
|
||||
INSIST(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
uv_udp_recv_stop(&sock->uv_handle.udp);
|
||||
uv_close((uv_handle_t *) &sock->uv_handle.udp, udp_close_cb);
|
||||
@@ -179,13 +181,15 @@ stop_udp_child(isc_nmsocket_t *sock) {
|
||||
|
||||
static void
|
||||
stoplistening(isc_nmsocket_t *sock) {
|
||||
INSIST(sock->type == isc_nm_udplistener);
|
||||
REQUIRE(sock->type == isc_nm_udplistener);
|
||||
|
||||
/*
|
||||
* Socket is already closing; there's nothing to do.
|
||||
*/
|
||||
if (!isc__nmsocket_active(sock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark it inactive now so that all sends will be ignored
|
||||
* and we won't try to stop listening again.
|
||||
@@ -195,7 +199,7 @@ stoplistening(isc_nmsocket_t *sock) {
|
||||
for (int i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_udpstop_t *event = NULL;
|
||||
|
||||
if (i == sock->tid) {
|
||||
if (isc_nm_tid() == sock->children[i].tid) {
|
||||
stop_udp_child(&sock->children[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user