From: Ondřej Surý Date: Wed, 17 Jun 2026 18:37:55 +0000 (+0200) Subject: Allocate work threads from their owning loop's memory context X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72ff42d2bfff1d6d780a86841a371798288661ba;p=thirdparty%2Fbind9.git Allocate work threads from their owning loop's memory context A per-loop work thread referenced the loop manager's memory context, which is not the context that backs the loop the thread serves. Pass the owning loop instead and allocate from loop->mctx, keeping a loop reference for the thread's lifetime. This matches how isc_work_enqueue and work_done already obtain the context from the loop, and the teardown uses loop->mctx before dropping the reference. --- diff --git a/lib/isc/include/isc/work.h b/lib/isc/include/isc/work.h index a4567f13f0d..8cb0c3f6d2f 100644 --- a/lib/isc/include/isc/work.h +++ b/lib/isc/include/isc/work.h @@ -85,7 +85,7 @@ isc_work_cancel(isc_work_t *work); typedef struct isc__workthread isc__workthread_t; isc__workthread_t * -isc__workthread_create(isc_mem_t *mctx, isc_worklane_t lane); +isc__workthread_create(isc_loop_t *loop, isc_worklane_t lane); /*%< * Create one worker thread for 'lane' with its own dispatch queue (the loop * manager creates one per loop). Used by the loop manager; not for general diff --git a/lib/isc/loop.c b/lib/isc/loop.c index 062bcfa599e..7828decb6ba 100644 --- a/lib/isc/loop.c +++ b/lib/isc/loop.c @@ -289,8 +289,7 @@ loop_thread(void *arg) { UV_RUNTIME_CHECK(uv_prepare_start, r); for (isc_worklane_t lane = 0; lane < ISC_WORKLANE_COUNT; lane++) { - loop->workthreads[lane] = - isc__workthread_create(isc__loopmgr->mctx, lane); + loop->workthreads[lane] = isc__workthread_create(loop, lane); } isc_barrier_wait(&loopmgr->starting); diff --git a/lib/isc/work.c b/lib/isc/work.c index c2af8cfe16a..c70d512b2ef 100644 --- a/lib/isc/work.c +++ b/lib/isc/work.c @@ -68,7 +68,7 @@ typedef struct isc__workthread { struct { unsigned int magic; isc_worklane_t lane; - isc_mem_t *mctx; + isc_loop_t *loop; isc_thread_t thread; struct __cds_wfcq_head qhead; int32_t state; /* enum waitstate */ @@ -339,14 +339,14 @@ isc_work_cancel(isc_work_t *work) { } isc__workthread_t * -isc__workthread_create(isc_mem_t *mctx, isc_worklane_t lane) { - isc__workthread_t *thread = isc_mem_get(mctx, sizeof(*thread)); +isc__workthread_create(isc_loop_t *loop, isc_worklane_t lane) { + isc__workthread_t *thread = isc_mem_get(loop->mctx, sizeof(*thread)); *thread = (isc__workthread_t){ .lane = lane, .magic = WORKTHREAD_MAGIC, .state = THREAD_WAITING, - .mctx = isc_mem_ref(mctx), + .loop = loop, }; __cds_wfcq_init(&thread->qhead, &thread->qtail); @@ -394,7 +394,7 @@ isc__workthread_destroy(isc__workthread_t **threadp) { INSIST(cds_wfcq_empty(&thread->qhead, &thread->qtail)); thread->magic = 0; - isc_mem_putanddetach(&thread->mctx, thread, sizeof(*thread)); + isc_mem_put(thread->loop->mctx, thread, sizeof(*thread)); } void