INSIST(VALID_NMHANDLE(httphandle));
- newcb = isc__nm_uvreq_get(httphandle->sock->worker,
- httphandle->sock);
+ newcb = isc__nm_uvreq_get(httphandle->sock);
newcb->cb.send = cb;
newcb->cbarg = cbarg;
isc_nmhandle_attach(httphandle, &newcb->handle);
atomic_init(&sock->client, true);
if (isc__nm_closing(worker)) {
- isc__nm_uvreq_t *req = isc__nm_uvreq_get(worker, sock);
+ isc__nm_uvreq_t *req = isc__nm_uvreq_get(sock);
req->cb.connect = cb;
req->cbarg = cbarg;
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_tid());
- uvreq = isc__nm_uvreq_get(sock->worker, sock);
+ uvreq = isc__nm_uvreq_get(sock);
isc_nmhandle_attach(handle, &uvreq->handle);
uvreq->cb.send = cb;
uvreq->cbarg = cbarg;
if (req->cb.send != NULL) {
isc__nm_sendcb(sock, req, eresult, true);
} else {
- isc__nm_uvreq_put(&req, sock);
+ isc__nm_uvreq_put(&req);
}
}
}
http_do_bio(sock->h2.session, handle, cb, cbarg);
- isc__nm_uvreq_put(&req, sock);
+ isc__nm_uvreq_put(&req);
}
static void
} else {
cb(handle, result, cbarg);
}
- isc__nm_uvreq_put(&req, sock);
+ isc__nm_uvreq_put(&req);
}
static void
ievent->file = file; \
ievent->line = line; \
ievent->func = func;
-#define isc__nm_uvreq_get(req, sock) \
- isc___nm_uvreq_get(req, sock, __FILE__, __LINE__, __func__)
-#define isc__nm_uvreq_put(req, sock) \
- isc___nm_uvreq_put(req, sock, __FILE__, __LINE__, __func__)
+#define isc__nm_uvreq_get(sock) \
+ isc___nm_uvreq_get(sock, __FILE__, __LINE__, __func__)
+#define isc__nm_uvreq_put(req) \
+ isc___nm_uvreq_put(req, __FILE__, __LINE__, __func__)
#define isc__nmsocket_init(sock, mgr, type, iface, parent) \
isc___nmsocket_init(sock, mgr, type, iface, parent, __FILE__, \
__LINE__, __func__)
#define FLARG_PASS
#define FLARG_IEVENT(ievent)
#define FLARG_IEVENT_PASS(ievent)
-#define isc__nm_uvreq_get(req, sock) isc___nm_uvreq_get(req, sock)
-#define isc__nm_uvreq_put(req, sock) isc___nm_uvreq_put(req, sock)
+#define isc__nm_uvreq_get(sock) isc___nm_uvreq_get(sock)
+#define isc__nm_uvreq_put(req) isc___nm_uvreq_put(req)
#define isc__nmsocket_init(sock, mgr, type, iface, parent) \
isc___nmsocket_init(sock, mgr, type, iface, parent)
#define isc__nmsocket_put(sockp) isc___nmsocket_put(sockp)
isc_nm_timer_t *timer; /* TCP write timer */
int connect_tries; /* connect retries */
isc_result_t result;
+ uv_idle_t idle;
union {
uv_handle_t handle;
uv_connect_t connect;
uv_udp_send_t udp_send;
uv_fs_t fs;
- uv_idle_t idle;
} uv_req;
ISC_LINK(isc__nm_uvreq_t) link;
- ISC_LINK(isc__nm_uvreq_t) inactive_link;
+ ISC_LINK(isc__nm_uvreq_t) active_link;
};
/*
atomic_bool keepalive;
/*%
- * 'spare' handles for that can be reused to avoid allocations,
- * for UDP.
+ * 'spare' handles for that can be reused to avoid allocations, for UDP.
*/
ISC_LIST(isc_nmhandle_t) inactive_handles;
+ /*%
+ * 'active' handles and uvreqs, mostly for debugging purposes.
+ */
+ ISC_LIST(isc_nmhandle_t) active_handles;
+ ISC_LIST(isc__nm_uvreq_t) active_uvreqs;
+
/*%
* Used to pass a result back from listen or connect events.
*/
int backtrace_size;
#endif
LINK(isc_nmsocket_t) active_link;
- ISC_LIST(isc_nmhandle_t) active_handles;
};
void
*/
isc__nm_uvreq_t *
-isc___nm_uvreq_get(isc__networker_t *worker, isc_nmsocket_t *sock FLARG);
+isc___nm_uvreq_get(isc_nmsocket_t *sock FLARG);
/*%<
* Get a UV request structure for the socket 'sock', allocating a
* new one if there isn't one available in 'sock->inactivereqs'.
*/
void
-isc___nm_uvreq_put(isc__nm_uvreq_t **req, isc_nmsocket_t *sock FLARG);
+isc___nm_uvreq_put(isc__nm_uvreq_t **req FLARG);
/*%<
* Completes the use of a UV request structure, setting '*req' to NULL.
*
#include "openssl_shim.h"
#include "trampoline_p.h"
-/*%
- * How many isc_nmhandles and isc_nm_uvreqs will we be
- * caching for reuse in a socket.
- */
-#define ISC_NM_HANDLES_STACK_SIZE 600
-#define ISC_NM_REQS_STACK_SIZE 600
-
/*%
* Shortcut index arrays to get access to statistics counters.
*/
static void
nmhandle_free(isc_nmsocket_t *sock, isc_nmhandle_t *handle);
+static void
+uvreq_free(uv_handle_t *handle);
+
/*%<
* Issue a 'handle closed' callback on the socket.
*/
isc_mempool_create(worker->mctx, sizeof(isc__nm_uvreq_t),
&worker->uvreq_pool);
- isc_mempool_setfreemax(worker->uvreq_pool,
- ISC_NM_REQS_STACK_SIZE);
isc_loop_attach(loop, &worker->loop);
isc_loop_teardown(loop, networker_teardown, worker);
return (handle);
}
#else
- UNUSED(sock);
+ INSIST(ISC_LIST_EMPTY(sock->inactive_handles));
#endif /* !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__ */
return (NULL);
}
if (req->cb.send != NULL) {
isc__nm_sendcb(sock, req, eresult, async);
} else {
- isc__nm_uvreq_put(&req, sock);
+ isc__nm_uvreq_put(&req);
}
}
isc__nm_get_read_req(isc_nmsocket_t *sock, isc_sockaddr_t *sockaddr) {
isc__nm_uvreq_t *req = NULL;
- req = isc__nm_uvreq_get(sock->worker, sock);
+ req = isc__nm_uvreq_get(sock);
req->cb.recv = sock->recv_cb;
req->cbarg = sock->recv_cbarg;
}
isc__nm_uvreq_t *
-isc___nm_uvreq_get(isc__networker_t *worker, isc_nmsocket_t *sock FLARG) {
- isc__nm_uvreq_t *req = NULL;
-
- REQUIRE(worker != NULL);
+isc___nm_uvreq_get(isc_nmsocket_t *sock FLARG) {
REQUIRE(VALID_NMSOCK(sock));
REQUIRE(sock->tid == isc_tid());
- req = isc_mempool_get(worker->uvreq_pool);
+ isc__networker_t *worker = sock->worker;
+
+ isc__nm_uvreq_t *req = isc_mempool_get(worker->uvreq_pool);
*req = (isc__nm_uvreq_t){
.connect_tries = 3,
.link = ISC_LINK_INITIALIZER,
- .inactive_link = ISC_LINK_INITIALIZER,
- .uv_req.req.data = req,
+ .active_link = ISC_LINK_INITIALIZER,
.magic = UVREQ_MAGIC,
};
+ uv_handle_set_data(&req->uv_req.handle, req);
+
+ int r = uv_idle_init(&worker->loop->loop, &req->idle);
+ UV_RUNTIME_CHECK(uv_idle_init, r);
+ uv_handle_set_data(&req->idle, req);
+
isc___nmsocket_attach(sock, &req->sock FLARG_PASS);
+ ISC_LIST_APPEND(sock->active_uvreqs, req, active_link);
+
return (req);
}
-void
-isc___nm_uvreq_put(isc__nm_uvreq_t **req0, isc_nmsocket_t *sock FLARG) {
- REQUIRE(req0 != NULL);
- REQUIRE(VALID_UVREQ(*req0));
- REQUIRE(VALID_NMSOCK(sock));
- REQUIRE(sock->tid == isc_tid());
+static void
+uvreq_free(uv_handle_t *handle) {
+ isc__nm_uvreq_t *req = uv_handle_get_data(handle);
+ isc_nmsocket_t *sock = req->sock;
- isc__nm_uvreq_t *req = NULL;
- isc_nmhandle_t *handle = NULL;
- isc__networker_t *worker = sock->worker;
+ isc_mempool_put(sock->worker->uvreq_pool, req);
- req = *req0;
- *req0 = NULL;
+ isc___nmsocket_detach(&sock FLARG_PASS);
+}
- INSIST(sock == req->sock);
+void
+isc___nm_uvreq_put(isc__nm_uvreq_t **reqp FLARG) {
+ REQUIRE(reqp != NULL && VALID_UVREQ(*reqp));
- req->magic = 0;
+ isc__nm_uvreq_t *req = *reqp;
+ isc_nmhandle_t *handle = req->handle;
+ isc_nmsocket_t *sock = req->sock;
- /*
- * We need to save this first to make sure that handle,
- * sock, and the netmgr won't all disappear.
- */
- ISC_SWAP(handle, req->handle);
+ *reqp = NULL;
+ req->handle = NULL;
- isc_mempool_put(worker->uvreq_pool, req);
+ REQUIRE(VALID_UVREQ(req));
+
+ ISC_LIST_UNLINK(sock->active_uvreqs, req, active_link);
if (handle != NULL) {
isc__nmhandle_detach(&handle FLARG_PASS);
}
- isc___nmsocket_detach(&sock FLARG_PASS);
+ uv_close(&req->idle, uvreq_free);
}
void
listener->barriers_initialised = true;
}
-static void
-isc__nm_uvreq_free(uv_handle_t *handle) {
- isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
-
- isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
-}
-
static void
isc___nm_connectcb(uv_idle_t *handle) {
isc__nm_uvreq_t *uvreq = uv_handle_get_data(handle);
uvreq->cb.connect(uvreq->handle, uvreq->result, uvreq->cbarg);
uv_idle_stop(handle);
- uv_close(handle, isc__nm_uvreq_free);
+ isc__nm_uvreq_put(&uvreq);
}
void
if (!async) {
uvreq->cb.connect(uvreq->handle, eresult, uvreq->cbarg);
- isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
+ isc__nm_uvreq_put(&uvreq);
return;
}
uvreq->result = eresult;
- uv_idle_init(&sock->worker->loop->loop, &uvreq->uv_req.idle);
- uv_idle_start(&uvreq->uv_req.idle, isc___nm_connectcb);
- uv_handle_set_data(&uvreq->uv_req.idle, uvreq);
+ uv_idle_start(&uvreq->idle, isc___nm_connectcb);
}
static void
uvreq->cb.recv(uvreq->handle, uvreq->result, ®ion, uvreq->cbarg);
uv_idle_stop(handle);
- uv_close(handle, isc__nm_uvreq_free);
+ isc__nm_uvreq_put(&uvreq);
}
void
region.length = uvreq->uvbuf.len;
uvreq->cb.recv(uvreq->handle, eresult, ®ion, uvreq->cbarg);
- isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
+ isc__nm_uvreq_put(&uvreq);
return;
}
uvreq->result = eresult;
- uv_idle_init(&sock->worker->loop->loop, &uvreq->uv_req.idle);
- uv_idle_start(&uvreq->uv_req.idle, isc___nm_readcb);
- uv_handle_set_data(&uvreq->uv_req.idle, uvreq);
+ uv_idle_start(&uvreq->idle, isc___nm_readcb);
}
static void
uvreq->cb.send(uvreq->handle, uvreq->result, uvreq->cbarg);
uv_idle_stop(handle);
- uv_close(handle, isc__nm_uvreq_free);
+ isc__nm_uvreq_put(&uvreq);
}
void
if (!async) {
uvreq->cb.send(uvreq->handle, uvreq->result, uvreq->cbarg);
- isc__nm_uvreq_put(&uvreq, uvreq->handle->sock);
+ isc__nm_uvreq_put(&uvreq);
return;
}
- uv_idle_init(&sock->worker->loop->loop, &uvreq->uv_req.idle);
- uv_idle_start(&uvreq->uv_req.idle, isc___nm_sendcb);
- uv_handle_set_data(&uvreq->uv_req.idle, uvreq);
+ uv_idle_start(&uvreq->idle, isc___nm_sendcb);
}
static void