From: Ondřej Surý Date: Mon, 10 May 2021 12:11:25 +0000 (+0200) Subject: Destroy reference to taskmgr after all tasks are done X-Git-Tag: v9.17.13~6^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e623c12757b071ecf07696b9d35a7d3668aa7dfa;p=thirdparty%2Fbind9.git Destroy reference to taskmgr after all tasks are done We were clearing the pointer to taskmgr as soon as isc_taskmgr_destroy() would be called and before all tasks were finished. Unfortunately, some tasks would use global named_g_taskmgr objects from inside the events and this would cause either a data race or NULL pointer dereference. This commit fixes the data race by moving the destruction of the referenced pointer to the time after all tasks are finished. --- diff --git a/lib/isc/task.c b/lib/isc/task.c index abdcb56cdd8..9225a2284f1 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -1074,26 +1074,22 @@ isc__taskmgr_shutdown(isc_taskmgr_t *manager) { void isc__taskmgr_destroy(isc_taskmgr_t **managerp) { REQUIRE(managerp != NULL && VALID_MANAGER(*managerp)); - - isc_taskmgr_t *manager = *managerp; - *managerp = NULL; - XTHREADTRACE("isc_taskmgr_destroy"); #ifdef ISC_TASK_TRACE int counter = 0; - while (isc_refcount_current(&manager->references) > 1 && + while (isc_refcount_current(&(*managerp)->references) > 1 && counter++ < 1000) { usleep(10 * 1000); } + INSIST(counter < 1000); #else - while (isc_refcount_current(&manager->references) > 1) { + while (isc_refcount_current(&(*managerp)->references) > 1) { usleep(10 * 1000); } #endif - REQUIRE(isc_refcount_decrement(&manager->references) == 1); - manager_free(manager); + isc_taskmgr_detach(managerp); } void