From 7c93964aaf41b1747b932ced38d1681b766a07c0 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Fri, 23 Oct 1998 23:50:15 +0000 Subject: [PATCH] use isc_thread_join() to wait for workers to exit --- lib/isc/task.c | 52 +++++++++++++++++++------------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/lib/isc/task.c b/lib/isc/task.c index c7e6bc1e57..3386539c1b 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -83,14 +83,14 @@ struct isc_taskmgr { unsigned int magic; isc_memctx_t mctx; isc_mutex_t lock; + unsigned int workers; + isc_thread_t * threads; /* Locked by task manager lock. */ unsigned int default_quantum; LIST(struct isc_task) tasks; LIST(struct isc_task) ready_tasks; isc_condition_t work_available; isc_boolean_t exiting; - unsigned int workers; - isc_condition_t no_workers; }; #define DEFAULT_DEFAULT_QUANTUM 5 @@ -441,7 +441,6 @@ WINAPI run(void *uap) { isc_taskmgr_t manager = uap; isc_task_t task; - isc_boolean_t no_workers = ISC_FALSE; 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); - if (no_workers) - BROADCAST(&manager->no_workers); - XTRACE("exit"); return ((isc_threadresult_t)0); @@ -685,8 +677,9 @@ run(void *uap) { static void manager_free(isc_taskmgr_t manager) { (void)isc_condition_destroy(&manager->work_available); - (void)isc_condition_destroy(&manager->no_workers); (void)isc_mutex_destroy(&manager->lock); + isc_mem_put(manager->mctx, manager->threads, + manager->workers * sizeof (isc_thread_t)); manager->magic = 0; 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; isc_taskmgr_t manager; - isc_thread_t thread; + isc_thread_t *threads; REQUIRE(workers > 0); @@ -706,7 +699,15 @@ isc_taskmgr_create(isc_memctx_t mctx, unsigned int workers, return (ISC_R_NOMEMORY); manager->magic = TASK_MANAGER_MAGIC; 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) { + isc_mem_put(mctx, threads, workers * sizeof (isc_thread_t)); isc_mem_put(mctx, manager, sizeof *manager); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_mutex_init() failed"); @@ -719,6 +720,7 @@ isc_taskmgr_create(isc_memctx_t mctx, unsigned int workers, INIT_LIST(manager->ready_tasks); if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) { (void)isc_mutex_destroy(&manager->lock); + isc_mem_put(mctx, threads, workers * sizeof (isc_thread_t)); isc_mem_put(mctx, manager, sizeof *manager); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() failed"); @@ -726,25 +728,17 @@ isc_taskmgr_create(isc_memctx_t mctx, unsigned int workers, } manager->exiting = ISC_FALSE; 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); /* * Start workers. */ 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) { manager->workers++; started++; - (void)isc_thread_detach(thread); } } UNLOCK(&manager->lock); @@ -763,6 +757,7 @@ void isc_taskmgr_destroy(isc_taskmgr_t *managerp) { isc_taskmgr_t manager; isc_task_t task; + unsigned int i; REQUIRE(managerp != NULL); manager = *managerp; @@ -824,20 +819,13 @@ isc_taskmgr_destroy(isc_taskmgr_t *managerp) { * it will cause the workers to see manager->exiting. */ BROADCAST(&manager->work_available); + UNLOCK(&manager->lock); /* * 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) - WAIT(&manager->no_workers, &manager->lock); - - UNLOCK(&manager->lock); + for (i = 0; i < manager->workers; i++) + (void)isc_thread_join(manager->threads[i], NULL); manager_free(manager);