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.
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;
* 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);
* Close a TCP socket.
*/
+void
+isc__nm_tcp_shutdown(isc_nmsocket_t *sock);
+/*%<
+ * Called on shutdown to close and clean up a listening TCP socket.
+ */
+
void
isc__nm_async_tcpconnect(isc__networker_t *worker, isc__netievent_t *ievent0);
void
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.
*/
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();
isc_nmsocket_detach(&ievent->sock);
}
+static void
+shutdown_walk_cb(uv_handle_t *handle, void *arg) {
+ isc_nmsocket_t *sock = NULL;
+
+ UNUSED(arg);
+
+ switch(handle->type) {
+ case UV_TCP:
+ isc__nm_tcp_shutdown((isc_nmsocket_t *) handle->data);
+ 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);
tcp_close_direct(ievent->sock);
}
+
+void
+isc__nm_tcp_shutdown(isc_nmsocket_t *sock) {
+ REQUIRE(VALID_NMSOCK(sock));
+
+ sock->rcb.recv(sock->tcphandle, NULL, sock->rcbarg);
+}