destroy_managers(void) {
ns_lwresd_shutdown();
- isc_entropy_detach(&ns_g_entropy);
- if (ns_g_fallbackentropy != NULL)
- isc_entropy_detach(&ns_g_fallbackentropy);
-
/*
* isc_taskmgr_destroy() will block until all tasks have exited,
*/
ns_server_destroy(&ns_g_server);
+ isc_entropy_detach(&ns_g_entropy);
+ if (ns_g_fallbackentropy != NULL)
+ isc_entropy_detach(&ns_g_fallbackentropy);
+
ns_builtin_deinit();
/*
isc_boolean_t pause_requested;
isc_boolean_t exclusive_requested;
isc_boolean_t exiting;
+
+ /*
+ * Multiple threads can read/write 'excl' at the same time, so we need
+ * to protect the access. We can't use 'lock' since isc_task_detach()
+ * will try to acquire it.
+ */
+ isc_mutex_t excl_lock;
isc__task_t *excl;
#ifdef USE_SHARED_MANAGER
unsigned int refs;
isc_mem_free(manager->mctx, manager->threads);
#endif /* USE_WORKER_THREADS */
DESTROYLOCK(&manager->lock);
+ DESTROYLOCK(&manager->excl_lock);
manager->common.impmagic = 0;
manager->common.magic = 0;
mctx = manager->mctx;
result = isc_mutex_init(&manager->lock);
if (result != ISC_R_SUCCESS)
goto cleanup_mgr;
+ result = isc_mutex_init(&manager->excl_lock);
+ if (result != ISC_R_SUCCESS) {
+ DESTROYLOCK(&manager->lock);
+ goto cleanup_mgr;
+ }
#ifdef USE_WORKER_THREADS
manager->workers = 0;
/*
* Detach the exclusive task before acquiring the manager lock
*/
+ LOCK(&manager->excl_lock);
if (manager->excl != NULL)
isc__task_detach((isc_task_t **) &manager->excl);
+ UNLOCK(&manager->excl_lock);
/*
* Unlike elsewhere, we're going to hold this lock a long time.
REQUIRE(VALID_MANAGER(mgr));
REQUIRE(VALID_TASK(task));
+ LOCK(&mgr->excl_lock);
if (mgr->excl != NULL)
isc__task_detach((isc_task_t **) &mgr->excl);
isc__task_attach(task0, (isc_task_t **) &mgr->excl);
+ UNLOCK(&mgr->excl_lock);
}
isc_result_t
isc_taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) {
isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0;
+ isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_MANAGER(mgr));
REQUIRE(taskp != NULL && *taskp == NULL);
- if (mgr->excl == NULL)
- return (ISC_R_NOTFOUND);
+ LOCK(&mgr->excl_lock);
+ if (mgr->excl != NULL)
+ isc__task_attach((isc_task_t *) mgr->excl, taskp);
+ else
+ result = ISC_R_NOTFOUND;
+ UNLOCK(&mgr->excl_lock);
- isc__task_attach((isc_task_t *) mgr->excl, taskp);
- return (ISC_R_SUCCESS);
+ return (result);
}
isc_result_t