From 8e3d4e7b7aa96cb045b67fe98574a958c92a9249 Mon Sep 17 00:00:00 2001 From: Michael Ploujnikov Date: Wed, 25 Nov 2009 11:06:53 -0500 Subject: [PATCH] fixed lumiera_threadpool_destroy() by using LLIST_FOREACH added some checks to lumiera_threadpool_release_thread(), maybe too much modified thread_loop() to return a known value - 0 added checks to lumiera_thread_new() added a check to lumiera_thread_destroy() made lumiera_thread_destroy() unlink the thread from a pool list updated test case to match new debug messages --- src/backend/threadpool.c | 21 ++++++++++++--------- src/backend/threads.c | 13 ++++++++++--- tests/30backend-threadpool.tests | 30 ++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/backend/threadpool.c b/src/backend/threadpool.c index 970e7291c..5960c890f 100644 --- a/src/backend/threadpool.c +++ b/src/backend/threadpool.c @@ -65,16 +65,17 @@ lumiera_threadpool_init(void) void lumiera_threadpool_destroy(void) { + ECHO ("destroying threadpool"); for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i) { + ECHO ("destroying individual pool #%d", i); // no locking is done at this point - LLIST_FOREACH(&threadpool.kind[i].pool, thread) - { - llist_unlink(thread); - lumiera_thread_delete((LumieraThread)thread); - } - + ECHO ("number of threads in the pool=%d", llist_count(&threadpool.kind[i].pool)); + LLIST_WHILE_HEAD(&threadpool.kind[i].pool, thread) + lumiera_thread_delete((LumieraThread)thread); + ECHO ("destroying the pool mutex"); lumiera_mutex_destroy (&threadpool.kind[i].lock, &NOBUG_FLAG (threadpool)); + ECHO ("pool mutex destroyed"); } } @@ -109,9 +110,11 @@ lumiera_threadpool_acquire_thread(enum lumiera_thread_class kind, void lumiera_threadpool_release_thread(LumieraThread thread) { - // TODO: do we need to check that index 'kind' is within range? - llist pool = threadpool.kind[thread->kind].pool; - llist_insert_head(&pool, &thread->node); + REQUIRE (thread, "invalid thread given"); + REQUIRE (thread->kind < LUMIERA_THREADCLASS_COUNT, "thread belongs to an unknown pool kind: %d", thread->kind); + REQUIRE (llist_is_single(&thread->node), "thread already belongs to some list"); + llist_insert_head(&threadpool.kind[thread->kind].pool, &thread->node); + REQUIRE (!llist_is_empty (&threadpool.kind[thread->kind].pool), "thread pool is still empty after insertion"); } /* diff --git a/src/backend/threads.c b/src/backend/threads.c index 6104a8011..4471fb444 100644 --- a/src/backend/threads.c +++ b/src/backend/threads.c @@ -55,7 +55,8 @@ struct lumiera_thread_mockup static void* thread_loop (void* arg) { - return arg; + (void)arg; + return 0; } #if 0 @@ -165,10 +166,12 @@ lumiera_thread_new (enum lumiera_thread_class kind, if (attr_once == PTHREAD_ONCE_INIT) pthread_once (&attr_once, thread_attr_init); + REQUIRE (kind < LUMIERA_THREADCLASS_COUNT, "invalid thread kind specified: %d", kind); + //REQUIRE (finished, "invalid finished flag passed"); + LumieraThread self = lumiera_malloc (sizeof (*self)); llist_init(&self->node); self->finished = finished; - REQUIRE (kind < LUMIERA_THREADCLASS_COUNT, "invalid thread kind specified: %d", kind); self->kind = kind; self->state = LUMIERA_THREADSTATE_IDLE; @@ -190,8 +193,11 @@ lumiera_thread_new (enum lumiera_thread_class kind, LumieraThread lumiera_thread_destroy (LumieraThread self) { + ECHO ("destroying thread"); + REQUIRE (self, "trying to destroy an invalid thread"); + // TODO: stop the pthread - // TODO: empty the list/node? + llist_unlink(&self->node); //finished = NULL; // or free(finished)? lumiera_reccondition_destroy (self->finished, &NOBUG_FLAG(threads)); //kind = 0; @@ -202,6 +208,7 @@ lumiera_thread_destroy (LumieraThread self) void lumiera_thread_delete (LumieraThread self) { + ECHO ("deleting thread"); lumiera_free (lumiera_thread_destroy (self)); } diff --git a/tests/30backend-threadpool.tests b/tests/30backend-threadpool.tests index 16fd316d4..a23ff38ea 100644 --- a/tests/30backend-threadpool.tests +++ b/tests/30backend-threadpool.tests @@ -13,5 +13,35 @@ err: releasing thread 1 err: thread 1 has been released err: releasing thread 2 err: thread 2 has been released +err: destroying threadpool + +err: destroying individual pool #0 +err: number of threads in the pool=1 +err: deleting thread +err: destroying thread +err: destroying the pool mutex +err: pool mutex destroyed + +err: destroying individual pool #1 +err: number of threads in the pool=0 +err: destroying the pool mutex +err: pool mutex destroyed + +err: destroying individual pool #2 +err: number of threads in the pool=0 +err: destroying the pool mutex +err: pool mutex destroyed + +err: destroying individual pool #3 +err: number of threads in the pool=0 +err: destroying the pool mutex +err: pool mutex destroyed + +err: destroying individual pool #4 +err: number of threads in the pool=1 +err: deleting thread +err: destroying thread +err: destroying the pool mutex +err: pool mutex destroyed END