2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

use isc_thread_join() to wait for workers to exit

This commit is contained in:
Bob Halley
1998-10-23 23:50:15 +00:00
parent b07a162e29
commit 7c93964aaf

View File

@@ -83,14 +83,14 @@ struct isc_taskmgr {
unsigned int magic; unsigned int magic;
isc_memctx_t mctx; isc_memctx_t mctx;
isc_mutex_t lock; isc_mutex_t lock;
unsigned int workers;
isc_thread_t * threads;
/* Locked by task manager lock. */ /* Locked by task manager lock. */
unsigned int default_quantum; unsigned int default_quantum;
LIST(struct isc_task) tasks; LIST(struct isc_task) tasks;
LIST(struct isc_task) ready_tasks; LIST(struct isc_task) ready_tasks;
isc_condition_t work_available; isc_condition_t work_available;
isc_boolean_t exiting; isc_boolean_t exiting;
unsigned int workers;
isc_condition_t no_workers;
}; };
#define DEFAULT_DEFAULT_QUANTUM 5 #define DEFAULT_DEFAULT_QUANTUM 5
@@ -441,7 +441,6 @@ WINAPI
run(void *uap) { run(void *uap) {
isc_taskmgr_t manager = uap; isc_taskmgr_t manager = uap;
isc_task_t task; isc_task_t task;
isc_boolean_t no_workers = ISC_FALSE;
XTRACE("start"); XTRACE("start");
@@ -668,15 +667,8 @@ run(void *uap) {
} }
} }
} }
INSIST(manager->workers > 0);
manager->workers--;
if (manager->workers == 0)
no_workers = ISC_TRUE;
UNLOCK(&manager->lock); UNLOCK(&manager->lock);
if (no_workers)
BROADCAST(&manager->no_workers);
XTRACE("exit"); XTRACE("exit");
return ((isc_threadresult_t)0); return ((isc_threadresult_t)0);
@@ -685,8 +677,9 @@ run(void *uap) {
static void static void
manager_free(isc_taskmgr_t manager) { manager_free(isc_taskmgr_t manager) {
(void)isc_condition_destroy(&manager->work_available); (void)isc_condition_destroy(&manager->work_available);
(void)isc_condition_destroy(&manager->no_workers);
(void)isc_mutex_destroy(&manager->lock); (void)isc_mutex_destroy(&manager->lock);
isc_mem_put(manager->mctx, manager->threads,
manager->workers * sizeof (isc_thread_t));
manager->magic = 0; manager->magic = 0;
isc_mem_put(manager->mctx, manager, sizeof *manager); isc_mem_put(manager->mctx, manager, sizeof *manager);
} }
@@ -697,7 +690,7 @@ isc_taskmgr_create(isc_memctx_t mctx, unsigned int workers,
{ {
unsigned int i, started = 0; unsigned int i, started = 0;
isc_taskmgr_t manager; isc_taskmgr_t manager;
isc_thread_t thread; isc_thread_t *threads;
REQUIRE(workers > 0); REQUIRE(workers > 0);
@@ -706,7 +699,15 @@ isc_taskmgr_create(isc_memctx_t mctx, unsigned int workers,
return (ISC_R_NOMEMORY); return (ISC_R_NOMEMORY);
manager->magic = TASK_MANAGER_MAGIC; manager->magic = TASK_MANAGER_MAGIC;
manager->mctx = mctx; manager->mctx = mctx;
threads = isc_mem_get(mctx, workers * sizeof (isc_thread_t));
if (threads == NULL) {
isc_mem_put(mctx, manager, sizeof *manager);
return (ISC_R_NOMEMORY);
}
manager->threads = threads;
manager->workers = 0;
if (isc_mutex_init(&manager->lock) != ISC_R_SUCCESS) { if (isc_mutex_init(&manager->lock) != ISC_R_SUCCESS) {
isc_mem_put(mctx, threads, workers * sizeof (isc_thread_t));
isc_mem_put(mctx, manager, sizeof *manager); isc_mem_put(mctx, manager, sizeof *manager);
UNEXPECTED_ERROR(__FILE__, __LINE__, UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_mutex_init() failed"); "isc_mutex_init() failed");
@@ -719,6 +720,7 @@ isc_taskmgr_create(isc_memctx_t mctx, unsigned int workers,
INIT_LIST(manager->ready_tasks); INIT_LIST(manager->ready_tasks);
if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) { if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) {
(void)isc_mutex_destroy(&manager->lock); (void)isc_mutex_destroy(&manager->lock);
isc_mem_put(mctx, threads, workers * sizeof (isc_thread_t));
isc_mem_put(mctx, manager, sizeof *manager); isc_mem_put(mctx, manager, sizeof *manager);
UNEXPECTED_ERROR(__FILE__, __LINE__, UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_condition_init() failed"); "isc_condition_init() failed");
@@ -726,25 +728,17 @@ isc_taskmgr_create(isc_memctx_t mctx, unsigned int workers,
} }
manager->exiting = ISC_FALSE; manager->exiting = ISC_FALSE;
manager->workers = 0; manager->workers = 0;
if (isc_condition_init(&manager->no_workers) != ISC_R_SUCCESS) {
(void)isc_condition_destroy(&manager->work_available);
(void)isc_mutex_destroy(&manager->lock);
isc_mem_put(mctx, manager, sizeof *manager);
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_condition_init() failed");
return (ISC_R_UNEXPECTED);
}
LOCK(&manager->lock); LOCK(&manager->lock);
/* /*
* Start workers. * Start workers.
*/ */
for (i = 0; i < workers; i++) { for (i = 0; i < workers; i++) {
if (isc_thread_create(run, manager, &thread) == if (isc_thread_create(run, manager,
&manager->threads[manager->workers]) ==
ISC_R_SUCCESS) { ISC_R_SUCCESS) {
manager->workers++; manager->workers++;
started++; started++;
(void)isc_thread_detach(thread);
} }
} }
UNLOCK(&manager->lock); UNLOCK(&manager->lock);
@@ -763,6 +757,7 @@ void
isc_taskmgr_destroy(isc_taskmgr_t *managerp) { isc_taskmgr_destroy(isc_taskmgr_t *managerp) {
isc_taskmgr_t manager; isc_taskmgr_t manager;
isc_task_t task; isc_task_t task;
unsigned int i;
REQUIRE(managerp != NULL); REQUIRE(managerp != NULL);
manager = *managerp; manager = *managerp;
@@ -824,20 +819,13 @@ isc_taskmgr_destroy(isc_taskmgr_t *managerp) {
* it will cause the workers to see manager->exiting. * it will cause the workers to see manager->exiting.
*/ */
BROADCAST(&manager->work_available); BROADCAST(&manager->work_available);
UNLOCK(&manager->lock);
/* /*
* Wait for all the worker threads to exit. * Wait for all the worker threads to exit.
*
* XXX This will become a timed wait. If all the workers haven't
* died after we've waited the specified interval, we will
* kill the worker threads. Should we join with the worker
* threads after killing them or just leave them detached and
* hope they go away?
*/ */
while (manager->workers > 0) for (i = 0; i < manager->workers; i++)
WAIT(&manager->no_workers, &manager->lock); (void)isc_thread_join(manager->threads[i], NULL);
UNLOCK(&manager->lock);
manager_free(manager); manager_free(manager);