2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

Create the spillattimer when needed and destroy it early

Instead of creating dns_resolver .spillattimer when the dns_resolver_t
object is created, create it on the current loop as needed and destroy
it as soon as the timer has finished its job.  This avoids the need to
manipulate the timer from a different thread.
This commit is contained in:
Ondřej Surý 2022-09-12 14:51:33 +02:00 committed by Evan Hunt
parent f16c46173c
commit a56f9d5061

View File

@ -17,6 +17,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h> #include <stdbool.h>
#include <isc/async.h>
#include <isc/atomic.h> #include <isc/atomic.h>
#include <isc/counter.h> #include <isc/counter.h>
#include <isc/hash.h> #include <isc/hash.h>
@ -1738,12 +1739,14 @@ fcount_decr(fetchctx_t *fctx) {
UNLOCK(&zbucket->lock); UNLOCK(&zbucket->lock);
} }
static void
spillattimer_countdown(void *arg);
static void static void
fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) { fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
dns_fetchevent_t *event, *next_event; dns_fetchevent_t *event, *next_event;
isc_task_t *task; isc_task_t *task;
unsigned int count = 0; unsigned int count = 0;
isc_interval_t i;
bool logit = false; bool logit = false;
isc_time_t now; isc_time_t now;
unsigned int old_spillat; unsigned int old_spillat;
@ -1822,9 +1825,20 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
if (new_spillat != old_spillat) { if (new_spillat != old_spillat) {
logit = true; logit = true;
} }
isc_interval_set(&i, 20 * 60, 0);
isc_timer_start(fctx->res->spillattimer, /* Timer not running */
isc_timertype_ticker, &i); if (fctx->res->spillattimer == NULL) {
isc_interval_t i;
isc_timer_create(
isc_loop_current(fctx->res->loopmgr),
spillattimer_countdown, fctx->res,
&fctx->res->spillattimer);
isc_interval_set(&i, 20 * 60, 0);
isc_timer_start(fctx->res->spillattimer,
isc_timertype_ticker, &i);
}
} }
UNLOCK(&fctx->res->lock); UNLOCK(&fctx->res->lock);
if (logit) { if (logit) {
@ -10196,7 +10210,7 @@ destroy(dns_resolver_t *res) {
isc_mem_put(res->mctx, a, sizeof(*a)); isc_mem_put(res->mctx, a, sizeof(*a));
} }
dns_badcache_destroy(&res->badcache); dns_badcache_destroy(&res->badcache);
isc_timer_destroy(&res->spillattimer);
dns_view_weakdetach(&res->view); dns_view_weakdetach(&res->view);
isc_mem_putanddetach(&res->mctx, res, sizeof(*res)); isc_mem_putanddetach(&res->mctx, res, sizeof(*res));
} }
@ -10204,26 +10218,28 @@ destroy(dns_resolver_t *res) {
static void static void
spillattimer_countdown(void *arg) { spillattimer_countdown(void *arg) {
dns_resolver_t *res = (dns_resolver_t *)arg; dns_resolver_t *res = (dns_resolver_t *)arg;
unsigned int count; unsigned int spillat = 0;
bool logit = false;
REQUIRE(VALID_RESOLVER(res)); REQUIRE(VALID_RESOLVER(res));
if (atomic_load(&res->exiting)) {
isc_timer_destroy(&res->spillattimer);
return;
}
LOCK(&res->lock); LOCK(&res->lock);
INSIST(!atomic_load_acquire(&res->exiting)); INSIST(!atomic_load_acquire(&res->exiting));
if (res->spillat > res->spillatmin) { if (res->spillat > res->spillatmin) {
res->spillat--; spillat = --res->spillat;
logit = true;
} }
if (res->spillat <= res->spillatmin) { if (res->spillat <= res->spillatmin) {
isc_timer_stop(res->spillattimer); isc_timer_destroy(&res->spillattimer);
} }
count = res->spillat;
UNLOCK(&res->lock); UNLOCK(&res->lock);
if (logit) { if (spillat > 0) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE, DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
"clients-per-query decreased to %u", count); "clients-per-query decreased to %u", spillat);
} }
} }
@ -10236,7 +10252,6 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
isc_result_t result = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS;
char name[sizeof("res4294967295")]; char name[sizeof("res4294967295")];
dns_resolver_t *res = NULL; dns_resolver_t *res = NULL;
isc_loop_t *loop = NULL;
/* /*
* Create a resolver. * Create a resolver.
@ -10324,10 +10339,6 @@ dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
isc_mutex_init(&res->lock); isc_mutex_init(&res->lock);
isc_mutex_init(&res->primelock); isc_mutex_init(&res->primelock);
loop = isc_loop_main(res->loopmgr);
isc_timer_create(loop, spillattimer_countdown, res, &res->spillattimer);
res->magic = RES_MAGIC; res->magic = RES_MAGIC;
*resp = res; *resp = res;
@ -10507,7 +10518,11 @@ dns_resolver_shutdown(dns_resolver_t *res) {
isc_ht_iter_destroy(&it); isc_ht_iter_destroy(&it);
RWUNLOCK(&res->hash_lock, isc_rwlocktype_read); RWUNLOCK(&res->hash_lock, isc_rwlocktype_read);
isc_timer_stop(res->spillattimer); LOCK(&res->lock);
if (res->spillattimer != NULL) {
isc_timer_async_destroy(&res->spillattimer);
}
UNLOCK(&res->lock);
} }
} }