thread: simplify 'free' process

GThread is freed using some very slightly confusing logic: if the thread
was created 'joinable', then the structure is freed after the join()
call succeeds (since we know the thread has exited).  If the thread was
not created 'joinable' then the free is when the thread quits (since we
know 'join' will not be called later).

Move to a straight ref-counting system: 1 ref owned by the thread and 1
extra ref if the thread is joinable.  Both thread quit and joining will
decrease the refcount by 1.
This commit is contained in:
Ryan Lortie 2011-10-13 00:18:17 -04:00
parent becb4b820f
commit 62be9365d9
2 changed files with 20 additions and 23 deletions

View File

@ -666,24 +666,24 @@ void
/* GThread {{{1 -------------------------------------------------------- */
static void
g_thread_unref (GThread *thread)
{
GRealThread *real = (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)
{
if (data)
{
GRealThread* thread = data;
/* 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);
}
}
g_thread_unref (data);
}
gpointer
@ -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);
}

View File

@ -59,6 +59,7 @@ struct _GRealThread
{
GThread thread;
gint ref_count;
gboolean ours;
const gchar *name;
gpointer retval;