mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 22:45:39 +00:00
Reduce the number of client tasks and bind them to netmgr queues
Since a client object is bound to a netmgr handle, each client will always be processed by the same netmgr worker, so we can simplify the code by binding client->task to the same thread as the client. Since ns__client_request() now runs in the same event loop as client->task events, is no longer necessary to pause the task manager before launching them. Also removed some functions in isc_task that were not used.
This commit is contained in:
119
lib/isc/task.c
119
lib/isc/task.c
@@ -78,15 +78,16 @@
|
||||
typedef enum {
|
||||
task_state_idle, /* not doing anything, events queue empty */
|
||||
task_state_ready, /* waiting in worker's queue */
|
||||
task_state_paused, /* not running, paused */
|
||||
task_state_pausing, /* running, waiting to be paused */
|
||||
task_state_running, /* actively processing events */
|
||||
task_state_done /* shutting down, no events or references */
|
||||
} task_state_t;
|
||||
|
||||
#if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C)
|
||||
static const char *statenames[] = {
|
||||
"idle", "ready", "paused", "pausing", "running", "done",
|
||||
"idle",
|
||||
"ready",
|
||||
"running",
|
||||
"done",
|
||||
};
|
||||
#endif /* if defined(HAVE_LIBXML2) || defined(HAVE_JSON_C) */
|
||||
|
||||
@@ -101,7 +102,6 @@ struct isc_task {
|
||||
int threadid;
|
||||
/* Locked by task lock. */
|
||||
task_state_t state;
|
||||
int pause_cnt;
|
||||
isc_refcount_t references;
|
||||
isc_refcount_t running;
|
||||
isc_eventlist_t events;
|
||||
@@ -237,7 +237,6 @@ isc_task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
||||
|
||||
isc_mutex_init(&task->lock);
|
||||
task->state = task_state_idle;
|
||||
task->pause_cnt = 0;
|
||||
|
||||
isc_refcount_init(&task->references, 1);
|
||||
isc_refcount_init(&task->running, 0);
|
||||
@@ -312,8 +311,6 @@ task_shutdown(isc_task_t *task) {
|
||||
was_idle = true;
|
||||
}
|
||||
INSIST(task->state == task_state_ready ||
|
||||
task->state == task_state_paused ||
|
||||
task->state == task_state_pausing ||
|
||||
task->state == task_state_running);
|
||||
|
||||
/*
|
||||
@@ -437,9 +434,7 @@ task_send(isc_task_t *task, isc_event_t **eventp, int c) {
|
||||
task->state = task_state_ready;
|
||||
}
|
||||
INSIST(task->state == task_state_ready ||
|
||||
task->state == task_state_running ||
|
||||
task->state == task_state_paused ||
|
||||
task->state == task_state_pausing);
|
||||
task->state == task_state_running);
|
||||
ENQUEUE(task->events, event, ev_link);
|
||||
task->nevents++;
|
||||
|
||||
@@ -779,26 +774,6 @@ isc_task_gettag(isc_task_t *task) {
|
||||
return (task->tag);
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
REQUIRE(t != NULL);
|
||||
|
||||
LOCK(&task->lock);
|
||||
*t = task->now;
|
||||
UNLOCK(&task->lock);
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_getcurrenttimex(isc_task_t *task, isc_time_t *t) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
REQUIRE(t != NULL);
|
||||
|
||||
LOCK(&task->lock);
|
||||
*t = task->tnow;
|
||||
UNLOCK(&task->lock);
|
||||
}
|
||||
|
||||
/***
|
||||
*** Task Manager.
|
||||
***/
|
||||
@@ -813,11 +788,7 @@ task_run(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
LOCK(&task->lock);
|
||||
/*
|
||||
* It is possible because that we have a paused task in the queue - it
|
||||
* might have been paused in the meantime and we never hold both queue
|
||||
* and task lock to avoid deadlocks, just bail then.
|
||||
*/
|
||||
/* FIXME */
|
||||
if (task->state != task_state_ready) {
|
||||
goto done;
|
||||
}
|
||||
@@ -885,24 +856,11 @@ task_run(isc_task_t *task) {
|
||||
*/
|
||||
XTRACE("done");
|
||||
task->state = task_state_done;
|
||||
} else {
|
||||
if (task->state == task_state_running) {
|
||||
XTRACE("idling");
|
||||
task->state = task_state_idle;
|
||||
} else if (task->state == task_state_pausing) {
|
||||
XTRACE("pausing");
|
||||
task->state = task_state_paused;
|
||||
}
|
||||
} else if (task->state == task_state_running) {
|
||||
XTRACE("idling");
|
||||
task->state = task_state_idle;
|
||||
}
|
||||
break;
|
||||
} else if (task->state == task_state_pausing) {
|
||||
/*
|
||||
* We got a pause request on this task, stop working on
|
||||
* it and switch the state to paused.
|
||||
*/
|
||||
XTRACE("pausing");
|
||||
task->state = task_state_paused;
|
||||
break;
|
||||
} else if (dispatch_count >= task->quantum) {
|
||||
/*
|
||||
* Our quantum has expired, but there is more work to be
|
||||
@@ -1164,65 +1122,6 @@ isc_task_endexclusive(isc_task_t *task) {
|
||||
&(bool){ true }, false));
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_pause(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
LOCK(&task->lock);
|
||||
task->pause_cnt++;
|
||||
if (task->pause_cnt > 1) {
|
||||
/*
|
||||
* Someone already paused this task, just increase
|
||||
* the number of pausing clients.
|
||||
*/
|
||||
UNLOCK(&task->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
INSIST(task->state == task_state_idle ||
|
||||
task->state == task_state_ready ||
|
||||
task->state == task_state_running);
|
||||
if (task->state == task_state_running) {
|
||||
task->state = task_state_pausing;
|
||||
} else {
|
||||
task->state = task_state_paused;
|
||||
}
|
||||
UNLOCK(&task->lock);
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_unpause(isc_task_t *task) {
|
||||
bool was_idle = false;
|
||||
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
LOCK(&task->lock);
|
||||
task->pause_cnt--;
|
||||
INSIST(task->pause_cnt >= 0);
|
||||
if (task->pause_cnt > 0) {
|
||||
UNLOCK(&task->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
INSIST(task->state == task_state_paused ||
|
||||
task->state == task_state_pausing);
|
||||
/* If the task was pausing we can't reschedule it */
|
||||
if (task->state == task_state_pausing) {
|
||||
task->state = task_state_running;
|
||||
} else {
|
||||
task->state = task_state_idle;
|
||||
}
|
||||
if (task->state == task_state_idle && !EMPTY(task->events)) {
|
||||
task->state = task_state_ready;
|
||||
was_idle = true;
|
||||
}
|
||||
UNLOCK(&task->lock);
|
||||
|
||||
if (was_idle) {
|
||||
task_ready(task);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode) {
|
||||
atomic_store(&manager->mode, mode);
|
||||
|
Reference in New Issue
Block a user