From 3807800d8293abd464196e57e4f18ba5b2cc6111 Mon Sep 17 00:00:00 2001 From: Jack Moffitt Date: Thu, 14 Feb 2002 00:41:57 +0000 Subject: [PATCH] Fix race condition on thread shutdown. svn path=/trunk/icecast/; revision=3045 --- src/stats.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/stats.c b/src/stats.c index d5638438..47b52817 100644 --- a/src/stats.c +++ b/src/stats.c @@ -33,6 +33,7 @@ typedef struct _event_listener_tag int _stats_running = 1; long _stats_thread_id; +int _stats_threads = 0; stats_t _stats; mutex_t _stats_mutex; @@ -79,11 +80,20 @@ void stats_initialize() void stats_shutdown() { + int n; /* wait for thread to exit */ _stats_running = 0; thread_join(_stats_thread_id); + /* wait for other threads to shut down */ + do { + thread_sleep(300000); + thread_mutex_lock(&_stats_mutex); + n = _stats_threads; + thread_mutex_unlock(&_stats_mutex); + } while (n > 0); + /* free the queues */ /* destroy the queue mutexes */ @@ -579,11 +589,16 @@ void *stats_connection(void *arg) mutex_t local_event_mutex; stats_event_t *event; + /* increment the thread count */ + thread_mutex_lock(&_stats_mutex); + _stats_threads++; + thread_mutex_unlock(&_stats_mutex); + thread_mutex_create(&local_event_mutex); _atomic_get_and_register(&local_event_queue, &local_event_mutex); - while (global.running == ICE_RUNNING) { + while (_stats_running) { thread_mutex_lock(&local_event_mutex); event = _get_event_from_queue(&local_event_queue); if (event != NULL) { @@ -596,7 +611,6 @@ void *stats_connection(void *arg) } else { thread_mutex_unlock(&local_event_mutex); thread_cond_wait(&_event_signal_cond); - if (!_stats_running) break; continue; } @@ -605,6 +619,10 @@ void *stats_connection(void *arg) thread_mutex_destroy(&local_event_mutex); + thread_mutex_lock(&_stats_mutex); + _stats_threads--; + thread_mutex_unlock(&_stats_mutex); + thread_exit(0); return NULL; @@ -626,11 +644,15 @@ void *stats_callback(void *arg) callback = arg; + thread_mutex_lock(&_stats_mutex); + _stats_threads++; + thread_mutex_unlock(&_stats_mutex); + thread_mutex_create(&local_event_mutex); _atomic_get_and_register(&local_event_queue, &local_event_mutex); - while (global.running == ICE_RUNNING) { + while (_stats_running) { thread_mutex_lock(&local_event_mutex); event = _get_event_from_queue(&local_event_queue); if (event != NULL) { @@ -639,7 +661,6 @@ void *stats_callback(void *arg) } else { thread_mutex_unlock(&local_event_mutex); thread_cond_wait(&_event_signal_cond); - if (!_stats_running) break; continue; } @@ -648,6 +669,10 @@ void *stats_callback(void *arg) thread_mutex_destroy(&local_event_mutex); + thread_mutex_lock(&_stats_mutex); + _stats_threads--; + thread_mutex_unlock(&_stats_mutex); + thread_exit(0); return NULL;