LIST(isc_task_t) tasks;
atomic_uint_fast32_t mode;
atomic_bool exclusive_req;
- atomic_bool 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;
+ bool exiting;
isc_task_t *excl;
};
INIT_LINK(task, link);
task->magic = TASK_MAGIC;
- exiting = false;
LOCK(&manager->lock);
- if (!atomic_load_relaxed(&manager->exiting)) {
+ exiting = manager->exiting;
+ if (!exiting) {
APPEND(manager->tasks, task, link);
atomic_fetch_add(&manager->tasks_count, 1);
- } else {
- exiting = true;
}
UNLOCK(&manager->lock);
isc_nm_detach(&manager->netmgr);
isc_mutex_destroy(&manager->lock);
- isc_mutex_destroy(&manager->excl_lock);
manager->magic = 0;
isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager));
}
*manager = (isc_taskmgr_t){ .magic = TASK_MANAGER_MAGIC };
isc_mutex_init(&manager->lock);
- isc_mutex_init(&manager->excl_lock);
if (default_quantum == 0) {
default_quantum = DEFAULT_DEFAULT_QUANTUM;
}
INIT_LIST(manager->tasks);
- atomic_init(&manager->exiting, false);
atomic_init(&manager->mode, isc_taskmgrmode_normal);
atomic_init(&manager->exclusive_req, false);
atomic_init(&manager->tasks_count, 0);
* that the startup thread is sleeping on.
*/
- /*
- * 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.
* We need to do so, because otherwise the list of tasks could
* This is also the only function where we will hold both the
* task manager lock and a task lock at the same time.
*/
-
LOCK(&manager->lock);
+ if (manager->excl != NULL) {
+ isc_task_detach((isc_task_t **)&manager->excl);
+ }
/*
* Make sure we only get called once.
*/
- INSIST(atomic_compare_exchange_strong(&manager->exiting,
- &(bool){ false }, true));
+ INSIST(manager->exiting == false);
+ manager->exiting = true;
/*
* Post shutdown event(s) to every task (if they haven't already been
REQUIRE(task->threadid == 0);
UNLOCK(&task->lock);
- LOCK(&mgr->excl_lock);
+ LOCK(&mgr->lock);
if (mgr->excl != NULL) {
isc_task_detach(&mgr->excl);
}
isc_task_attach(task, &mgr->excl);
- UNLOCK(&mgr->excl_lock);
+ UNLOCK(&mgr->lock);
}
isc_result_t
REQUIRE(VALID_MANAGER(mgr));
REQUIRE(taskp != NULL && *taskp == NULL);
- LOCK(&mgr->excl_lock);
+ LOCK(&mgr->lock);
if (mgr->excl != NULL) {
isc_task_attach(mgr->excl, taskp);
result = ISC_R_SUCCESS;
- } else if (atomic_load_relaxed(&mgr->exiting)) {
+ } else if (mgr->exiting) {
result = ISC_R_SHUTTINGDOWN;
} else {
result = ISC_R_NOTFOUND;
}
- UNLOCK(&mgr->excl_lock);
+ UNLOCK(&mgr->lock);
return (result);
}
REQUIRE(task->state == task_state_running);
- LOCK(&manager->excl_lock);
- REQUIRE(task == task->manager->excl ||
- (atomic_load_relaxed(&task->manager->exiting) &&
- task->manager->excl == NULL));
- UNLOCK(&manager->excl_lock);
+ LOCK(&manager->lock);
+ REQUIRE(task == manager->excl ||
+ (manager->exiting && manager->excl == NULL));
+ UNLOCK(&manager->lock);
if (!atomic_compare_exchange_strong(&manager->exclusive_req,
&(bool){ false }, true))