Dispatch async work jobs from the correct loop

Refactor dns_loadctx_t and dns_dumpctx_t to use standard
ISC_REFCOUNT_DECL and ISC_REFCOUNT_IMPL macros, retiring the
redundant manual attach and detach implementations.

Introduce dns_loadctx_enqueue() and dns_dumpctx_enqueue() to
ensure compliance with the new strict loop affinity in
isc_work_enqueue(). If the current loop does not match the
target loop, the enqueue operation is safely bounced to the
correct thread via isc_async_run().

(cherry picked from commit e7c550730a)
This commit is contained in:
Ondřej Surý 2026-03-10 18:25:54 +01:00
parent d4b96af062
commit 51a0151113
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
2 changed files with 42 additions and 52 deletions

View file

@ -45,6 +45,8 @@
#include <dns/time.h>
#include <dns/ttl.h>
#include "dns/types.h"
/*!
* Grow the number of dns_rdatalist_t (#RDLSZ) and dns_rdata_t (#RDSZ)
* structures by these sizes when we need to.
@ -400,29 +402,8 @@ gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, bool eol,
return ISC_R_SUCCESS;
}
void
dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) {
REQUIRE(target != NULL && *target == NULL);
REQUIRE(DNS_LCTX_VALID(source));
isc_refcount_increment(&source->references);
*target = source;
}
void
dns_loadctx_detach(dns_loadctx_t **lctxp) {
dns_loadctx_t *lctx;
REQUIRE(lctxp != NULL);
lctx = *lctxp;
*lctxp = NULL;
REQUIRE(DNS_LCTX_VALID(lctx));
if (isc_refcount_decrement(&lctx->references) == 1) {
loadctx_destroy(lctx);
}
}
ISC_REFCOUNT_DECL(dns_loadctx);
ISC_REFCOUNT_IMPL(dns_loadctx, loadctx_destroy);
static void
incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) {
@ -2696,6 +2677,21 @@ load_done(void *arg) {
dns_loadctx_detach(&lctx);
}
static void
load_enqueue(void *lctx) {
isc_work_enqueue(isc_loop(), load, load_done, lctx);
}
static void
dns_loadctx_enqueue(isc_loop_t *loop, dns_loadctx_t *lctx) {
dns_loadctx_ref(lctx);
if (loop == isc_loop()) {
load_enqueue(lctx);
} else {
isc_async_run(loop, load_enqueue, lctx);
}
}
isc_result_t
dns_master_loadfileasync(const char *master_file, dns_name_t *top,
dns_name_t *origin, dns_rdataclass_t zclass,
@ -2724,8 +2720,8 @@ dns_master_loadfileasync(const char *master_file, dns_name_t *top,
return result;
}
dns_loadctx_attach(lctx, lctxp);
isc_work_enqueue(loop, load, load_done, lctx);
dns_loadctx_enqueue(loop, lctx);
*lctxp = lctx;
return ISC_R_SUCCESS;
}

View file

@ -1387,29 +1387,8 @@ dumpctx_destroy(dns_dumpctx_t *dctx) {
isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(*dctx));
}
void
dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target) {
REQUIRE(DNS_DCTX_VALID(source));
REQUIRE(target != NULL && *target == NULL);
isc_refcount_increment(&source->references);
*target = source;
}
void
dns_dumpctx_detach(dns_dumpctx_t **dctxp) {
dns_dumpctx_t *dctx;
REQUIRE(dctxp != NULL);
dctx = *dctxp;
*dctxp = NULL;
REQUIRE(DNS_DCTX_VALID(dctx));
if (isc_refcount_decrement(&dctx->references) == 1) {
dumpctx_destroy(dctx);
}
}
ISC_REFCOUNT_DECL(dns_dumpctx);
ISC_REFCOUNT_IMPL(dns_dumpctx, dumpctx_destroy);
dns_dbversion_t *
dns_dumpctx_version(dns_dumpctx_t *dctx) {
@ -1777,6 +1756,21 @@ cleanup:
return result;
}
static void
master_dump_enqueue(void *dctx) {
isc_work_enqueue(isc_loop(), master_dump_cb, master_dump_done_cb, dctx);
}
static void
dns_dumpctx_enqueue(isc_loop_t *loop, dns_dumpctx_t *dctx) {
dns_dumpctx_ref(dctx);
if (loop == isc_loop()) {
master_dump_enqueue(dctx);
} else {
isc_async_run(loop, master_dump_enqueue, dctx);
}
}
isc_result_t
dns_master_dumptostreamasync(isc_mem_t *mctx, dns_db_t *db,
dns_dbversion_t *version,
@ -1798,8 +1792,8 @@ dns_master_dumptostreamasync(isc_mem_t *mctx, dns_db_t *db,
dctx->done = done;
dctx->done_arg = done_arg;
dns_dumpctx_attach(dctx, dctxp);
isc_work_enqueue(loop, master_dump_cb, master_dump_done_cb, dctx);
dns_dumpctx_enqueue(loop, dctx);
*dctxp = dctx;
return ISC_R_SUCCESS;
}
@ -1893,8 +1887,8 @@ dns_master_dumpasync(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
dctx->file = file;
dctx->tmpfile = tempname;
dns_dumpctx_attach(dctx, dctxp);
isc_work_enqueue(loop, master_dump_cb, master_dump_done_cb, dctx);
dns_dumpctx_enqueue(loop, dctx);
*dctxp = dctx;
return ISC_R_SUCCESS;