Commit f75a9e32 authored by Witold Krecicki's avatar Witold Krecicki

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.
parent 16908ec3
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment