From 2eae7813b608cd174cf3b9976cbd4f651e68a194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 6 May 2021 09:03:33 +0200 Subject: [PATCH] Run isc__nm_http_stoplistening() synchronously in netmgr When isc__nm_http_stoplistening() is run from inside the netmgr, we need to make sure it's run synchronously. This commit is just a band-aid though, as the desired behvaior for isc_nm_stoplistening() is not always the same: 1. When run from outside user of the interface, the call must be synchronous, e.g. the calling code expects the call to really stop listening on the interfaces. 2. But if there's a call from listen when listening fails, that needs to be scheduled to run asynchronously, because isc_nm_listen is being run in a paused (interlocked) netmgr thread and we could get stuck. The proper solution would be to make isc_nm_stoplistening() behave like uv_close(), i.e., to have a proper callback. --- lib/isc/netmgr/http.c | 15 +++++++++------ lib/isc/netmgr/tlsstream.c | 6 ++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c index 4482e2023d..021feaa3c3 100644 --- a/lib/isc/netmgr/http.c +++ b/lib/isc/netmgr/http.c @@ -2239,8 +2239,6 @@ isc_nm_http_endpoint(isc_nmsocket_t *sock, const char *uri, isc_nm_recv_cb_t cb, void isc__nm_http_stoplistening(isc_nmsocket_t *sock) { - isc__netievent_httpstop_t *ievent = NULL; - REQUIRE(VALID_NMSOCK(sock)); REQUIRE(sock->type == isc_nm_httplistener); @@ -2250,9 +2248,15 @@ isc__nm_http_stoplistening(isc_nmsocket_t *sock) { ISC_UNREACHABLE(); } - ievent = isc__nm_get_netievent_httpstop(sock->mgr, sock); - isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], - (isc__netievent_t *)ievent); + if (!isc__nm_in_netthread()) { + isc__netievent_httpstop_t *ievent = + isc__nm_get_netievent_httpstop(sock->mgr, sock); + isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid], + (isc__netievent_t *)ievent); + } else { + isc__netievent_httpstop_t ievent = { .sock = sock }; + isc__nm_async_httpstop(NULL, (isc__netievent_t *)&ievent); + } } static void @@ -2294,7 +2298,6 @@ isc__nm_async_httpstop(isc__networker_t *worker, isc__netievent_t *ev0) { UNUSED(worker); REQUIRE(VALID_NMSOCK(sock)); - REQUIRE(sock->tid == isc_nm_tid()); atomic_store(&sock->listening, false); atomic_store(&sock->closing, false); diff --git a/lib/isc/netmgr/tlsstream.c b/lib/isc/netmgr/tlsstream.c index 264ffcde41..fab2072f22 100644 --- a/lib/isc/netmgr/tlsstream.c +++ b/lib/isc/netmgr/tlsstream.c @@ -849,6 +849,12 @@ isc__nm_tls_stoplistening(isc_nmsocket_t *sock) { REQUIRE(VALID_NMSOCK(sock)); REQUIRE(sock->type == isc_nm_tlslistener); + if (!atomic_compare_exchange_strong(&sock->closing, &(bool){ false }, + true)) { + INSIST(0); + ISC_UNREACHABLE(); + } + atomic_store(&sock->listening, false); atomic_store(&sock->closed, true); sock->recv_cb = NULL;