2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00

Simplify netmgr active handles accounting

The active handles accounting was both using atomic counter and ISC_LIST
to keep track of active handles.  Remove the atomic counter that was in
use before the ISC_LIST was added for better tracking of the handles
attached to the socket.
This commit is contained in:
Ondřej Surý
2023-03-23 09:47:47 +01:00
parent 96cff4fc51
commit 5a43be0775
3 changed files with 52 additions and 58 deletions

View File

@@ -991,11 +991,6 @@ struct isc_nmsocket {
*/ */
isc_result_t result; isc_result_t result;
/*%
* Current number of active handles.
*/
atomic_int_fast32_t ah;
/*% /*%
* This function will be called with handle->sock * This function will be called with handle->sock
* as the argument whenever a handle's references drop * as the argument whenever a handle's references drop

View File

@@ -587,7 +587,9 @@ isc___nmsocket_attach(isc_nmsocket_t *sock, isc_nmsocket_t **target FLARG) {
* Free all resources inside a socket (including its children if any). * Free all resources inside a socket (including its children if any).
*/ */
static void static void
nmsocket_cleanup(isc_nmsocket_t *sock) { nmsocket_cleanup(void *arg) {
isc_nmsocket_t *sock = arg;
REQUIRE(VALID_NMSOCK(sock)); REQUIRE(VALID_NMSOCK(sock));
REQUIRE(!isc__nmsocket_active(sock)); REQUIRE(!isc__nmsocket_active(sock));
@@ -666,11 +668,26 @@ nmsocket_cleanup(isc_nmsocket_t *sock) {
isc__networker_detach(&worker); isc__networker_detach(&worker);
} }
static bool
nmsocket_has_active_handles(isc_nmsocket_t *sock) {
if (!ISC_LIST_EMPTY(sock->active_handles)) {
return (true);
}
if (sock->children != NULL) {
for (size_t i = 0; i < sock->nchildren; i++) {
isc_nmsocket_t *csock = &sock->children[i];
if (!ISC_LIST_EMPTY(csock->active_handles)) {
return (true);
}
}
}
return (false);
}
static void static void
nmsocket_maybe_destroy(isc_nmsocket_t *sock FLARG) { nmsocket_maybe_destroy(isc_nmsocket_t *sock FLARG) {
int active_handles;
bool destroy = false;
NETMGR_TRACE_LOG("%s():%p->references = %" PRIuFAST32 "\n", __func__, NETMGR_TRACE_LOG("%s():%p->references = %" PRIuFAST32 "\n", __func__,
sock, isc_refcount_current(&sock->references)); sock, isc_refcount_current(&sock->references));
@@ -684,39 +701,29 @@ nmsocket_maybe_destroy(isc_nmsocket_t *sock FLARG) {
return; return;
} }
/*
* This is a parent socket (or a standalone). See whether the
* children have active handles before deciding whether to
* accept destruction.
*/
if (atomic_load(&sock->active) || atomic_load(&sock->destroying) || if (atomic_load(&sock->active) || atomic_load(&sock->destroying) ||
!atomic_load(&sock->closed) || atomic_load(&sock->references) != 0) !atomic_load(&sock->closed) || atomic_load(&sock->references) != 0)
{ {
return; return;
} }
active_handles = atomic_load(&sock->ah); NETMGR_TRACE_LOG("%s:%p->statichandle = %p\n", __func__, sock,
if (sock->children != NULL) { sock->statichandle);
for (size_t i = 0; i < sock->nchildren; i++) {
active_handles += atomic_load(&sock->children[i].ah); /*
} * This is a parent socket (or a standalone). See whether the
* children have active handles before deciding whether to
* accept destruction.
*/
if (sock->statichandle == NULL && nmsocket_has_active_handles(sock)) {
return;
} }
if (active_handles == 0 || sock->statichandle != NULL) { atomic_store(&sock->destroying, true);
destroy = true; if (sock->tid == isc_tid()) {
} nmsocket_cleanup(sock);
} else {
NETMGR_TRACE_LOG("%s:%p->active_handles = %d, .statichandle = %p\n", isc_async_run(sock->worker->loop, nmsocket_cleanup, sock);
__func__, sock, active_handles, sock->statichandle);
if (destroy) {
atomic_store(&sock->destroying, true);
if (sock->tid == isc_tid()) {
nmsocket_cleanup(sock);
} else {
isc_async_run(sock->worker->loop,
(isc_job_cb)nmsocket_cleanup, sock);
}
} }
} }
@@ -921,7 +928,6 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc__networker_t *worker,
atomic_init(&sock->listening, 0); atomic_init(&sock->listening, 0);
atomic_init(&sock->closed, 0); atomic_init(&sock->closed, 0);
atomic_init(&sock->destroying, 0); atomic_init(&sock->destroying, 0);
atomic_init(&sock->ah, 0);
atomic_init(&sock->client, 0); atomic_init(&sock->client, 0);
atomic_init(&sock->connecting, false); atomic_init(&sock->connecting, false);
atomic_init(&sock->keepalive, false); atomic_init(&sock->keepalive, false);
@@ -1025,8 +1031,6 @@ isc___nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t const *peer,
handle->local = sock->iface; handle->local = sock->iface;
} }
(void)atomic_fetch_add(&sock->ah, 1);
ISC_LIST_APPEND(sock->active_handles, handle, active_link); ISC_LIST_APPEND(sock->active_handles, handle, active_link);
switch (sock->type) { switch (sock->type) {
@@ -1088,32 +1092,15 @@ static void
nmhandle_free(isc_nmsocket_t *sock, isc_nmhandle_t *handle) { nmhandle_free(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
isc_refcount_destroy(&handle->references); isc_refcount_destroy(&handle->references);
handle->magic = 0;
if (handle->dofree != NULL) { if (handle->dofree != NULL) {
handle->dofree(handle->opaque); handle->dofree(handle->opaque);
} }
*handle = (isc_nmhandle_t){ .magic = 0 };
isc_mem_put(sock->worker->mctx, handle, sizeof(isc_nmhandle_t)); isc_mem_put(sock->worker->mctx, handle, sizeof(isc_nmhandle_t));
} }
static void
nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) {
uint_fast32_t ah = atomic_fetch_sub(&sock->ah, 1);
INSIST(ah > 0);
ISC_LIST_UNLINK(sock->active_handles, handle, active_link);
#if !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__
if (atomic_load(&sock->active)) {
ISC_LIST_APPEND(sock->inactive_handles, handle, inactive_link);
} else
#endif /* !__SANITIZE_ADDRESS__ && !__SANITIZE_THREAD__ */
{
nmhandle_free(sock, handle);
}
}
static void static void
isc__nm_closehandle_job(void *arg) { isc__nm_closehandle_job(void *arg) {
isc_nmsocket_t *sock = arg; isc_nmsocket_t *sock = arg;
@@ -1144,7 +1131,17 @@ nmhandle_destroy(isc_nmhandle_t *handle) {
sock->statichandle = NULL; sock->statichandle = NULL;
} }
nmhandle_deactivate(sock, handle); ISC_LIST_UNLINK(sock->active_handles, handle, active_link);
#if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_THREAD__)
nmhandle_free(sock, handle);
#else
if (atomic_load(&sock->active)) {
ISC_LIST_APPEND(sock->inactive_handles, handle, inactive_link);
} else {
nmhandle_free(sock, handle);
}
#endif
/* /*
* The handle is gone now. If the socket has a callback configured * The handle is gone now. If the socket has a callback configured

View File

@@ -101,7 +101,9 @@ streamdns_resumeread(isc_nmsocket_t *sock, isc_nmhandle_t *transphandle) {
static void static void
streamdns_readmore(isc_nmsocket_t *sock, isc_nmhandle_t *transphandle) { streamdns_readmore(isc_nmsocket_t *sock, isc_nmhandle_t *transphandle) {
streamdns_resumeread(sock, transphandle); streamdns_resumeread(sock, transphandle);
if (sock->streamdns.reading && atomic_load(&sock->ah) == 1) {
isc_nmhandle_t *handle = ISC_LIST_HEAD(sock->active_handles);
if (handle != NULL && ISC_LIST_NEXT(handle, active_link) == NULL) {
isc__nmsocket_timer_start(sock); isc__nmsocket_timer_start(sock);
} }
} }