diff --git a/lib/dns/master.c b/lib/dns/master.c index ce2dca13d4..4974999eeb 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -45,6 +45,8 @@ #include #include +#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. @@ -387,29 +389,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) { @@ -2621,6 +2602,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, @@ -2649,8 +2645,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; } diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index 07cd7c1762..e73f5d1b00 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -1354,29 +1354,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); isc_result_t dns_dumpctx_serial(dns_dumpctx_t *dctx, uint32_t *serial) { @@ -1728,6 +1707,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, @@ -1745,8 +1739,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; } @@ -1834,8 +1828,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; diff --git a/lib/isc/work.c b/lib/isc/work.c index 4391b2d2fa..0b7cdf5743 100644 --- a/lib/isc/work.c +++ b/lib/isc/work.c @@ -58,6 +58,7 @@ isc_work_enqueue(isc_loop_t *loop, isc_work_cb work_cb, int r; REQUIRE(VALID_LOOP(loop)); + REQUIRE(isc_loop() == loop); REQUIRE(work_cb != NULL); REQUIRE(after_work_cb != NULL); diff --git a/tests/isc/work_test.c b/tests/isc/work_test.c index 51ebbe99ae..60eb7f6c25 100644 --- a/tests/isc/work_test.c +++ b/tests/isc/work_test.c @@ -54,11 +54,7 @@ after_work_cb(void *arg ISC_ATTR_UNUSED) { static void work_enqueue_cb(void *arg ISC_ATTR_UNUSED) { - isc_tid_t tid = isc_loopmgr_nloops() - 1; - - isc_loop_t *loop = isc_loop_get(tid); - - isc_work_enqueue(loop, work_cb, after_work_cb, NULL); + isc_work_enqueue(isc_loop(), work_cb, after_work_cb, NULL); } ISC_RUN_TEST_IMPL(isc_work_enqueue) {