mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-04 02:06:18 +01:00
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:
parent
becb4b820f
commit
62be9365d9
@ -666,24 +666,24 @@ void
|
|||||||
|
|
||||||
/* GThread {{{1 -------------------------------------------------------- */
|
/* 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
|
static void
|
||||||
g_thread_cleanup (gpointer data)
|
g_thread_cleanup (gpointer data)
|
||||||
{
|
{
|
||||||
if (data)
|
g_thread_unref (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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer
|
gpointer
|
||||||
@ -812,6 +812,7 @@ g_thread_new_internal (const gchar *name,
|
|||||||
thread = g_system_thread_new (proxy, stack_size, error);
|
thread = g_system_thread_new (proxy, stack_size, error);
|
||||||
if (thread)
|
if (thread)
|
||||||
{
|
{
|
||||||
|
thread->ref_count = joinable ? 2 : 1;
|
||||||
thread->ours = TRUE;
|
thread->ours = TRUE;
|
||||||
thread->thread.joinable = joinable;
|
thread->thread.joinable = joinable;
|
||||||
thread->thread.func = func;
|
thread->thread.func = func;
|
||||||
@ -888,14 +889,7 @@ g_thread_join (GThread *thread)
|
|||||||
/* Just to make sure, this isn't used any more */
|
/* Just to make sure, this isn't used any more */
|
||||||
thread->joinable = 0;
|
thread->joinable = 0;
|
||||||
|
|
||||||
/* the thread structure for non-joinable threads is freed upon
|
g_thread_unref (thread);
|
||||||
* 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);
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -920,6 +914,8 @@ g_thread_self (void)
|
|||||||
* that are not created by GLib.
|
* that are not created by GLib.
|
||||||
*/
|
*/
|
||||||
thread = g_slice_new0 (GRealThread);
|
thread = g_slice_new0 (GRealThread);
|
||||||
|
thread->ref_count = 1;
|
||||||
|
|
||||||
g_private_set (&g_thread_specific_private, thread);
|
g_private_set (&g_thread_specific_private, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ struct _GRealThread
|
|||||||
{
|
{
|
||||||
GThread thread;
|
GThread thread;
|
||||||
|
|
||||||
|
gint ref_count;
|
||||||
gboolean ours;
|
gboolean ours;
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
gpointer retval;
|
gpointer retval;
|
||||||
|
Loading…
Reference in New Issue
Block a user