[glib/wip/gcleanup] gthreadpool: Initial support for cleaning up thread pool
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/gcleanup] gthreadpool: Initial support for cleaning up thread pool
- Date: Thu, 7 Nov 2013 22:03:01 +0000 (UTC)
commit 147780f74e744cb135780adb1c0cd2e281f67155
Author: Stef Walter <stefw gnome org>
Date: Thu Nov 7 22:40:04 2013 +0100
gthreadpool: Initial support for cleaning up thread pool
WIP
Some work needed to figure out better way to stop unused threads.
glib/gthreadpool.c | 34 +++++++++++++++++++++++++++++++++-
1 files changed, 33 insertions(+), 1 deletions(-)
---
diff --git a/glib/gthreadpool.c b/glib/gthreadpool.c
index 78684ab..f8b4ae1 100644
--- a/glib/gthreadpool.c
+++ b/glib/gthreadpool.c
@@ -107,6 +107,8 @@ struct _GRealThreadPool
static const gpointer wakeup_thread_marker = (gpointer) &g_thread_pool_new;
static gint wakeup_thread_serial = 0;
+static gint alive_threads = 0;
+
/* Here all unused threads are waiting */
static GAsyncQueue *unused_thread_queue = NULL;
static gint unused_threads = 0;
@@ -289,6 +291,8 @@ g_thread_pool_thread_proxy (gpointer data)
DEBUG_MSG (("thread %p started for pool %p.", g_thread_self (), pool));
+ g_atomic_int_add (&alive_threads, 1);
+
g_async_queue_lock (pool->queue);
while (TRUE)
@@ -378,6 +382,8 @@ g_thread_pool_thread_proxy (gpointer data)
}
}
+ g_atomic_int_add (&alive_threads, -1);
+
return NULL;
}
@@ -422,6 +428,23 @@ g_thread_pool_start_thread (GRealThreadPool *pool,
return TRUE;
}
+static void
+stop_all_unused_threads (void)
+{
+ /*
+ * FIXME: Making sure that no threads are left behind requires
+ * significant changes to the current implementation,
+ * so for now we'll signal and always wait 10 ms,
+ * allowing any threads that were already in the process
+ * of shutting down to execute their last instructions... ICK!
+ */
+ g_thread_pool_set_max_unused_threads (0);
+ while (alive_threads > 0)
+ g_usleep (10000);
+
+ g_async_queue_unref (unused_thread_queue);
+}
+
/**
* g_thread_pool_new:
* @func: a function to execute in the threads of the new thread pool
@@ -488,7 +511,10 @@ g_thread_pool_new (GFunc func,
G_LOCK (init);
if (!unused_thread_queue)
+ {
unused_thread_queue = g_async_queue_new ();
+ G_CLEANUP_FUNC (stop_all_unused_threads);
+ }
G_UNLOCK (init);
if (retval->pool.exclusive)
@@ -818,8 +844,14 @@ g_thread_pool_wakeup_and_stop_all (GRealThreadPool *pool)
pool->immediate = TRUE;
+ /*
+ * So here we're sending bogus data to the pool threads, which
+ * should cause them each to wake up, and check the above
+ * pool->imediate condition. However we don't want that
+ * data to be sorted (since it'll crash the sorter).
+ */
for (i = 0; i < pool->num_threads; i++)
- g_thread_pool_queue_push_unlocked (pool, GUINT_TO_POINTER (1));
+ g_async_queue_push_unlocked (pool->queue, GUINT_TO_POINTER (1));
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]