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:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user