]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
netmgr: add shutdown function
authorEvan Hunt <each@isc.org>
Fri, 22 Nov 2019 23:57:42 +0000 (15:57 -0800)
committerEvan Hunt <each@isc.org>
Sat, 23 Nov 2019 00:46:32 +0000 (16:46 -0800)
- new function isc_nm_shutdown() shuts down all active TCP connections,
  but does not destroy the netmgr.

bin/named/main.c
lib/isc/include/isc/netmgr.h
lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tcp.c
lib/isc/win32/libisc.def.in

index d707916a7c0b30ff96102361097cc35e8391abd9..1716de3532d123fc42f5472969caa1f74b40ec38 100644 (file)
@@ -939,11 +939,23 @@ create_managers(void) {
 static void
 destroy_managers(void) {
        /*
-        * isc_taskmgr_destroy() will block until all tasks have exited,
+        * isc_nm_closedown() closes all active connections, freeing
+        * attached clients and other resources and preventing new
+        * connections from being established, but it not does not
+        * stop all processing or destroy the netmgr yet.
+        */
+       isc_nm_closedown(named_g_nm);
+
+       /*
+        * isc_taskmgr_destroy() will block until all tasks have exited.
         */
        isc_taskmgr_destroy(&named_g_taskmgr);
        isc_timermgr_destroy(&named_g_timermgr);
        isc_socketmgr_destroy(&named_g_socketmgr);
+
+       /*
+        * At this point is safe to destroy the netmgr.
+        */
        isc_nm_destroy(&named_g_nm);
 }
 
index 82d32f0dc614c4977c3f66f5c4c9d36d137c4f59..157961609fb90815ea5388b5bc648f194b5024a8 100644 (file)
@@ -46,7 +46,16 @@ isc_nm_destroy(isc_nm_t **mgr0);
  * for all other references to be gone.
  */
 
-/* Return thread id of current thread, or ISC_NETMGR_TID_UNKNOWN */
+void
+isc_nm_closedown(isc_nm_t *mgr);
+/*%<
+ * Close down all active connections, freeing associated resources;
+ * prevent new connections from being established. This can optionally
+ * be called prior to shutting down the netmgr, to stop all processing
+ * before shutting down the task manager.
+ */
+
+/* Return thread ID of current thread, or ISC_NETMGR_TID_UNKNOWN */
 int
 isc_nm_tid(void);
 
index f2aa88af1a3f0eda370a64760be2a2fc27ce28ee..36ebd3aaa1aadd9b37cd8b2dba9e13a82f23c017 100644 (file)
@@ -182,7 +182,6 @@ typedef isc__netievent__socket_t isc__netievent_tcpstoplisten_t;
 typedef isc__netievent__socket_t isc__netievent_tcpclose_t;
 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 struct isc__netievent__socket_req {
@@ -242,6 +241,12 @@ struct isc_nm {
        atomic_uint_fast32_t    maxudp;
        atomic_bool             paused;
 
+       /*
+        * Acive connections are being closed and new connections are
+        * no longer allowed.
+        */
+       atomic_bool             closing;
+
        /*
         * A worker is actively waiting for other workers, for example to
         * stop listening; that means no other thread can do the same thing
@@ -582,15 +587,12 @@ isc__nm_async_startread(isc__networker_t *worker, isc__netievent_t *ievent0);
 void
 isc__nm_async_pauseread(isc__networker_t *worker, isc__netievent_t *ievent0);
 void
-isc__nm_async_resumeread(isc__networker_t *worker, isc__netievent_t *ievent0);
-void
 isc__nm_async_tcpclose(isc__networker_t *worker, isc__netievent_t *ievent0);
 /*%<
  * Callback handlers for asynchronous TCP events (connect, listen,
- * stoplisten, send, read, pauseread, resumeread, close).
+ * stoplisten, send, read, pause, close).
  */
 
-
 isc_result_t
 isc__nm_tcpdns_send(isc_nmhandle_t *handle, isc_region_t *region,
                    isc_nm_cb_t cb, void *cbarg);
index 2b02a54734dc364758a31939c6885cf8ebec941c..32569093a4b5359456df61a801bb9637d1374082 100644 (file)
@@ -297,26 +297,34 @@ isc_nm_detach(isc_nm_t **mgr0) {
        }
 }
 
+void
+isc_nm_closedown(isc_nm_t *mgr) {
+       REQUIRE(VALID_NM(mgr));
+
+       atomic_store(&mgr->closing, true);
+       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);
+       }
+}
 
 void
 isc_nm_destroy(isc_nm_t **mgr0) {
        isc_nm_t *mgr = NULL;
-       int references;
 
        REQUIRE(mgr0 != NULL);
        REQUIRE(VALID_NM(*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);
-       }
+       /*
+        * Close active connections.
+        */
+       isc_nm_closedown(mgr);
 
        /*
-        * Wait for the manager to be dereferenced elsehwere.
+        * Wait for the manager to be dereferenced elsewhere.
         */
        while (isc_refcount_current(&mgr->references) > 1) {
 #ifdef WIN32
@@ -325,11 +333,11 @@ isc_nm_destroy(isc_nm_t **mgr0) {
                        usleep(1000000);
 #endif
        }
-       references = isc_refcount_decrement(&mgr->references);
-       INSIST(references > 0);
-       if (references == 1) {
-               nm_destroy(&mgr);
-       }
+
+       /*
+        * Detach final reference.
+        */
+       isc_nm_detach(mgr0);
 }
 
 void
@@ -1185,8 +1193,6 @@ isc__nm_async_closecb(isc__networker_t *worker, isc__netievent_t *ievent0) {
 
 static void
 shutdown_walk_cb(uv_handle_t *handle, void *arg) {
-       isc_nmsocket_t *sock = NULL;
-
        UNUSED(arg);
 
        switch(handle->type) {
index bfe4af956d31b232ad3c20cab7f48ef3f23b9122..75dcd3a7e27985977cf2247f08b21602d62b070f 100644 (file)
@@ -438,7 +438,9 @@ accept_connection(isc_nmsocket_t *ssock) {
        REQUIRE(VALID_NMSOCK(ssock));
        REQUIRE(ssock->tid == isc_nm_tid());
 
-       if (!atomic_load_relaxed(&ssock->active)) {
+       if (!atomic_load_relaxed(&ssock->active) ||
+           atomic_load_relaxed(&ssock->mgr->closing))
+       {
                /* We're closing, bail */
                return (ISC_R_CANCELED);
        }
@@ -693,5 +695,7 @@ void
 isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
 
-       sock->rcb.recv(sock->tcphandle, NULL, sock->rcbarg);
+       if (sock->type == isc_nm_tcpsocket && sock->tcphandle != NULL) {
+               sock->rcb.recv(sock->tcphandle, NULL, sock->rcbarg);
+       }
 }
index 35faea7d55f5dd1d1169880e1c18e14ddd9298f4..e65855f187db7d64f31513b24a16913dc9424b7e 100644 (file)
@@ -444,6 +444,7 @@ isc_nmhandle_peeraddr
 isc_nmhandle_ref
 isc_nmhandle_setdata
 isc_nmhandle_unref
+isc_nm_closedown
 isc_nm_destroy
 isc_nm_detach
 isc_nm_listentcpdns