2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

3353. [bug] Use a single task for task exclusive operations.

[RT #29872]
This commit is contained in:
Mark Andrews
2012-07-19 23:00:21 +10:00
parent 77e3e9daf1
commit c965b18690
9 changed files with 123 additions and 7 deletions

View File

@@ -158,6 +158,7 @@ struct isc__taskmgr {
isc_boolean_t pause_requested;
isc_boolean_t exclusive_requested;
isc_boolean_t exiting;
isc__task_t *excl;
#ifdef USE_SHARED_MANAGER
unsigned int refs;
#endif /* ISC_PLATFORM_USETHREADS */
@@ -227,6 +228,10 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
unsigned int default_quantum, isc_taskmgr_t **managerp);
ISC_TASKFUNC_SCOPE void
isc__taskmgr_destroy(isc_taskmgr_t **managerp);
ISC_TASKFUNC_SCOPE void
isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0);
ISC_TASKFUNC_SCOPE isc_result_t
isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp);
ISC_TASKFUNC_SCOPE isc_result_t
isc__task_beginexclusive(isc_task_t *task);
ISC_TASKFUNC_SCOPE void
@@ -288,7 +293,9 @@ static isc_taskmgrmethods_t taskmgrmethods = {
isc__taskmgr_destroy,
isc__taskmgr_setmode,
isc__taskmgr_mode,
isc__task_create
isc__task_create,
isc__taskmgr_setexcltask,
isc__taskmgr_excltask
};
/***
@@ -1411,6 +1418,7 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
manager->exclusive_requested = ISC_FALSE;
manager->pause_requested = ISC_FALSE;
manager->exiting = ISC_FALSE;
manager->excl = NULL;
isc_mem_attach(mctx, &manager->mctx);
@@ -1494,6 +1502,12 @@ isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
* that the startup thread is sleeping on.
*/
/*
* Detach the exclusive task before acquiring the manager lock
*/
if (manager->excl != NULL)
isc__task_detach((isc_task_t **) &manager->excl);
/*
* Unlike elsewhere, we're going to hold this lock a long time.
* We need to do so, because otherwise the list of tasks could
@@ -1644,12 +1658,41 @@ isc__taskmgr_resume(isc_taskmgr_t *manager0) {
}
#endif /* USE_WORKER_THREADS */
ISC_TASKFUNC_SCOPE void
isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) {
isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0;
isc__task_t *task = (isc__task_t *) task0;
REQUIRE(VALID_MANAGER(mgr));
REQUIRE(VALID_TASK(task));
if (mgr->excl != NULL)
isc__task_detach((isc_task_t **) &mgr->excl);
isc__task_attach(task0, (isc_task_t **) &mgr->excl);
}
ISC_TASKFUNC_SCOPE isc_result_t
isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) {
isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0;
REQUIRE(VALID_MANAGER(mgr));
REQUIRE(taskp != NULL && *taskp == NULL);
if (mgr->excl == NULL)
return (ISC_R_NOTFOUND);
isc__task_attach((isc_task_t *) mgr->excl, taskp);
return (ISC_R_SUCCESS);
}
ISC_TASKFUNC_SCOPE isc_result_t
isc__task_beginexclusive(isc_task_t *task0) {
#ifdef USE_WORKER_THREADS
isc__task_t *task = (isc__task_t *)task0;
isc__taskmgr_t *manager = task->manager;
REQUIRE(task->state == task_state_running);
/* XXX: Require task == manager->excl? */
LOCK(&manager->lock);
if (manager->exclusive_requested) {
UNLOCK(&manager->lock);