From ea4e56b89d6aa97531e2917b8da65dfe0713b0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= Date: Fri, 22 Nov 2019 14:13:19 +0100 Subject: [PATCH] WiP: shutdown active sockets when shutting down netmgr --- lib/isc/netmgr/netmgr-int.h | 20 ++++++++++++++------ lib/isc/netmgr/netmgr.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 513d313828..d077aea653 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -116,12 +116,9 @@ typedef enum isc__netievent_type { netievent_tcpstoplisten, netievent_tcpclose, netievent_closecb, + netievent_shutdown, } isc__netievent_type; -typedef struct isc__netievent_stop { - isc__netievent_type type; -} isc__netievent_stop_t; - /* * We have to split it because we can read and write on a socket * simultaneously. @@ -187,6 +184,7 @@ typedef isc__netievent__socket_t isc__netievent_startread_t; typedef isc__netievent__socket_t isc__netievent_pauseread_t; typedef isc__netievent__socket_t isc__netievent_resumeread_t; typedef isc__netievent__socket_t isc__netievent_closecb_t; +typedef isc__netievent__socket_t isc__netievent_closecb_t; typedef struct isc__netievent__socket_req { isc__netievent_type type; @@ -209,10 +207,13 @@ typedef struct isc__netievent { isc__netievent_type type; } isc__netievent_t; +typedef isc__netievent_t isc__netievent_shutdown_t; +typedef isc__netievent_t isc__netievent_stop_t; + typedef union { isc__netievent_t ni; - isc__netievent_stop_t nis; - isc__netievent_udplisten_t niul; + isc__netievent__socket_t nis; + isc__netievent__socket_req_t nisr; isc__netievent_udpsend_t nius; } isc__netievent_storage_t; @@ -512,6 +513,13 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ievent0); * Issue a 'handle closed' callback on the socket. */ +void +isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ievent0); +/*%< + * Walk through all uv handles, get the underlying sockets and issue + * close on them. + */ + isc_result_t isc__nm_udp_send(isc_nmhandle_t *handle, isc_region_t *region, isc_nm_cb_t cb, void *cbarg); diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index cee9a0c25b..f6072e1d36 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -309,6 +309,12 @@ isc_nm_destroy(isc_nm_t **mgr0) { mgr = *mgr0; *mgr0 = NULL; + for (size_t i = 0; i < mgr->nworkers; i++) { + isc__netievent_t *event = NULL; + event = isc__nm_get_ievent(mgr, netievent_shutdown); + isc__nm_enqueue_ievent(&mgr->workers[i], event); + } + /* * Wait for the manager to be dereferenced elsehwere. */ @@ -512,6 +518,9 @@ async_cb(uv_async_t *handle) { case netievent_closecb: isc__nm_async_closecb(worker, ievent); break; + case netievent_shutdown: + isc__nm_async_shutdown(worker, ievent); + break; default: INSIST(0); ISC_UNREACHABLE(); @@ -1174,6 +1183,28 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ievent0) { isc_nmsocket_detach(&ievent->sock); } +static void +shutdown_walk_cb(uv_handle_t *handle, void *arg) { + UNUSED(arg); + isc_nmsocket_t *sock; + switch(handle->type) { + case UV_TCP: + case UV_UDP: + sock = (isc_nmsocket_t*) handle->data; + INSIST(VALID_NMSOCK(sock)); + isc__nmsocket_prep_destroy(sock); + break; + default: + break; + } +} + +void +isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ievent0) { + UNUSED(ievent0); + uv_walk(&worker->loop, shutdown_walk_cb, NULL); +} + bool isc__nm_acquire_interlocked(isc_nm_t *mgr) { LOCK(&mgr->lock);