summaryrefslogtreecommitdiff
path: root/glib/gthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'glib/gthread.c')
-rw-r--r--glib/gthread.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/glib/gthread.c b/glib/gthread.c
index 210d1254a..29b102d95 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -667,25 +667,25 @@ void
/* GThread {{{1 -------------------------------------------------------- */
static void
-g_thread_cleanup (gpointer data)
+g_thread_unref (GThread *thread)
{
- if (data)
- {
- GRealThread* thread = data;
+ GRealThread *real = (GRealThread *) thread;
- /* We only free the thread structure if it isn't joinable.
- * If it is, the structure is freed in g_thread_join()
- */
- if (!thread->thread.joinable)
- {
- if (thread->ours)
- g_system_thread_free (thread);
- else
- g_slice_free (GRealThread, thread);
- }
+ if (g_atomic_int_dec_and_test (&real->ref_count))
+ {
+ if (real->ours)
+ g_system_thread_free (real);
+ else
+ g_slice_free (GRealThread, real);
}
}
+static void
+g_thread_cleanup (gpointer data)
+{
+ g_thread_unref (data);
+}
+
gpointer
g_thread_proxy (gpointer data)
{
@@ -812,6 +812,7 @@ g_thread_new_internal (const gchar *name,
thread = g_system_thread_new (proxy, stack_size, error);
if (thread)
{
+ thread->ref_count = joinable ? 2 : 1;
thread->ours = TRUE;
thread->thread.joinable = joinable;
thread->thread.func = func;
@@ -888,14 +889,7 @@ g_thread_join (GThread *thread)
/* Just to make sure, this isn't used any more */
thread->joinable = 0;
- /* the thread structure for non-joinable threads is freed upon
- * thread end. We free the memory here. This will leave a loose end,
- * if a joinable thread is not joined.
- */
- if (real->ours)
- g_system_thread_free (real);
- else
- g_slice_free (GRealThread, real);
+ g_thread_unref (thread);
return retval;
}
@@ -920,6 +914,8 @@ g_thread_self (void)
* that are not created by GLib.
*/
thread = g_slice_new0 (GRealThread);
+ thread->ref_count = 1;
+
g_private_set (&g_thread_specific_private, thread);
}