#include <isc/buffer.h>
#include <isc/condition.h>
#include <isc/errno.h>
+#include <isc/job.h>
#include <isc/list.h>
#include <isc/log.h>
#include <isc/loop.h>
static void
process_netievent(void *arg);
-static void
-isc__nm_async_detach(isc__networker_t *worker, isc__netievent_t *ev0);
-
/*%<
* Issue a 'handle closed' callback on the socket.
*/
-static void
-nmhandle_detach_cb(isc_nmhandle_t **handlep FLARG);
-
static void
shutdown_walk_cb(uv_handle_t *handle, void *arg);
NETIEVENT_CASE(settlsctx);
NETIEVENT_CASE(sockstop);
-
- NETIEVENT_CASE(detach);
default:
UNREACHABLE();
}
NETIEVENT_SOCKET_REQ_DEF(tlssend);
-NETIEVENT_SOCKET_DEF(detach);
-
NETIEVENT_SOCKET_QUOTA_DEF(tcpaccept);
NETIEVENT_SOCKET_DEF(streamdnsread);
}
}
-void
-isc__nmhandle_detach(isc_nmhandle_t **handlep FLARG) {
- isc_nmsocket_t *sock = NULL;
- isc_nmhandle_t *handle = NULL;
-
- REQUIRE(handlep != NULL);
- REQUIRE(VALID_NMHANDLE(*handlep));
+static void
+isc__nm_closehandle_job(void *arg) {
+ isc_nmsocket_t *sock = arg;
- handle = *handlep;
- *handlep = NULL;
+ sock->closehandle_cb(sock);
- /*
- * If the closehandle_cb is set, it needs to run asynchronously to
- * ensure correct ordering of the isc__nm_process_sock_buffer().
- */
- sock = handle->sock;
- if (sock->tid == isc_tid() && sock->closehandle_cb == NULL) {
- nmhandle_detach_cb(&handle FLARG_PASS);
- } else {
- isc__netievent_detach_t *event =
- isc__nm_get_netievent_detach(sock->worker, sock);
- /*
- * we are using implicit "attach" as the last reference
- * need to be destroyed explicitly in the async callback
- */
- event->handle = handle;
- FLARG_IEVENT_PASS(event);
- isc__nm_enqueue_ievent(sock->worker, (isc__netievent_t *)event);
- }
+ isc__nmsocket_detach(&sock);
}
static void
-nmhandle_detach_cb(isc_nmhandle_t **handlep FLARG) {
- isc_nmsocket_t *sock = NULL;
- isc_nmhandle_t *handle = NULL;
-
- REQUIRE(handlep != NULL);
- REQUIRE(VALID_NMHANDLE(*handlep));
-
- handle = *handlep;
- *handlep = NULL;
-
- NETMGR_TRACE_LOG("isc__nmhandle_detach():%p->references = %" PRIuFAST32
- "\n",
- handle, isc_refcount_current(&handle->references) - 1);
-
- if (isc_refcount_decrement(&handle->references) > 1) {
- return;
- }
-
- /* We need an acquire memory barrier here */
- (void)isc_refcount_current(&handle->references);
+nmhandle_destroy(isc_nmhandle_t *handle) {
+ isc_nmsocket_t *sock = handle->sock;
- sock = handle->sock;
handle->sock = NULL;
if (handle->doreset != NULL) {
/*
* The handle is gone now. If the socket has a callback configured
* for that (e.g., to perform cleanup after request processing),
- * call it now..
+ * call it now asynchronously.
*/
if (sock->closehandle_cb != NULL) {
- sock->closehandle_cb(sock);
+ isc_job_run(sock->worker->netmgr->loopmgr,
+ isc__nm_closehandle_job, sock);
+ } else {
+ isc___nmsocket_detach(&sock FLARG_PASS);
}
+}
- isc___nmsocket_detach(&sock FLARG_PASS);
+void
+isc__nmhandle_detach(isc_nmhandle_t **handlep FLARG) {
+ isc_nmhandle_t *handle = NULL;
+
+ REQUIRE(handlep != NULL);
+ REQUIRE(VALID_NMHANDLE(*handlep));
+
+ handle = *handlep;
+ *handlep = NULL;
+
+ REQUIRE(handle->sock->tid == isc_tid());
+
+ NETMGR_TRACE_LOG("isc__nmhandle_detach():%p->references = %" PRIuFAST32
+ "\n",
+ handle, isc_refcount_current(&handle->references) - 1);
+
+ if (isc_refcount_decrement(&handle->references) == 1) {
+ nmhandle_destroy(handle);
+ }
}
void *
isc_job_run(sock->worker->netmgr->loopmgr, isc__nm_sendcb_job, uvreq);
}
-void
-isc__nm_async_detach(isc__networker_t *worker, isc__netievent_t *ev0) {
- isc__netievent_detach_t *ievent = (isc__netievent_detach_t *)ev0;
- FLARG_IEVENT(ievent);
-
- REQUIRE(VALID_NMSOCK(ievent->sock));
- REQUIRE(VALID_NMHANDLE(ievent->handle));
- REQUIRE(ievent->sock->tid == isc_tid());
-
- UNUSED(worker);
-
- nmhandle_detach_cb(&ievent->handle FLARG_PASS);
-}
-
static void
reset_shutdown(uv_handle_t *handle) {
isc_nmsocket_t *sock = uv_handle_get_data(handle);