Don't put threads created with g_thread_new() on the list

This lets us avoid the overhead of maintaining the global
list in the non-deprecated case.

https://bugzilla.gnome.org/show_bug.cgi?id=660635
This commit is contained in:
Matthias Clasen 2011-10-02 09:51:13 -04:00
parent 1909d2398a
commit 12287c8cc7
3 changed files with 56 additions and 32 deletions

View File

@ -155,7 +155,7 @@ g_thread_create (GThreadFunc func,
gboolean joinable, gboolean joinable,
GError **error) GError **error)
{ {
return g_thread_new_full (NULL, func, data, joinable, 0, error); return g_thread_new_internal (NULL, func, data, joinable, 0, TRUE, error);
} }
/** /**
@ -183,7 +183,7 @@ g_thread_create_full (GThreadFunc func,
GThreadPriority priority, GThreadPriority priority,
GError **error) GError **error)
{ {
return g_thread_new_full (NULL, func, data, joinable, stack_size, error); return g_thread_new_internal (NULL, func, data, joinable, stack_size, TRUE, error);
} }
/* GStaticMutex {{{1 ------------------------------------------------------ */ /* GStaticMutex {{{1 ------------------------------------------------------ */

View File

@ -585,6 +585,7 @@ struct _GRealThread
GArray *private_data; GArray *private_data;
GRealThread *next; GRealThread *next;
const gchar *name; const gchar *name;
gboolean enumerable;
gpointer retval; gpointer retval;
GSystemThread system_thread; GSystemThread system_thread;
}; };
@ -1102,21 +1103,24 @@ g_thread_cleanup (gpointer data)
*/ */
if (!thread->thread.joinable) if (!thread->thread.joinable)
{ {
GRealThread *t, *p; if (thread->enumerable)
G_LOCK (g_thread);
for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
{ {
if (t == thread) GRealThread *t, *p;
G_LOCK (g_thread);
for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
{ {
if (p) if (t == thread)
p->next = t->next; {
else if (p)
g_thread_all_threads = t->next; p->next = t->next;
break; else
g_thread_all_threads = t->next;
break;
}
} }
G_UNLOCK (g_thread);
} }
G_UNLOCK (g_thread);
/* Just to make sure, this isn't used any more */ /* Just to make sure, this isn't used any more */
g_system_thread_assign (thread->system_thread, zero_thread); g_system_thread_assign (thread->system_thread, zero_thread);
g_free (thread); g_free (thread);
@ -1183,7 +1187,7 @@ g_thread_new (const gchar *name,
gboolean joinable, gboolean joinable,
GError **error) GError **error)
{ {
return g_thread_new_full (name, func, data, joinable, 0, error); return g_thread_new_internal (name, func, data, joinable, 0, FALSE, error);
} }
/** /**
@ -1232,7 +1236,19 @@ g_thread_new_full (const gchar *name,
gsize stack_size, gsize stack_size,
GError **error) GError **error)
{ {
GRealThread* result; return g_thread_new_internal (name, func, data, joinable, stack_size, FALSE, error);
}
GThread *
g_thread_new_internal (const gchar *name,
GThreadFunc func,
gpointer data,
gboolean joinable,
gsize stack_size,
gboolean enumerable,
GError **error)
{
GRealThread *result;
GError *local_error = NULL; GError *local_error = NULL;
g_return_val_if_fail (func, NULL); g_return_val_if_fail (func, NULL);
@ -1242,12 +1258,13 @@ g_thread_new_full (const gchar *name,
result->thread.func = func; result->thread.func = func;
result->thread.data = data; result->thread.data = data;
result->private_data = NULL; result->private_data = NULL;
result->enumerable = enumerable;
result->name = name; result->name = name;
G_LOCK (g_thread); G_LOCK (g_thread);
g_system_thread_create (g_thread_create_proxy, result, g_system_thread_create (g_thread_create_proxy, result,
stack_size, joinable, stack_size, joinable,
&result->system_thread, &local_error); &result->system_thread, &local_error);
if (!local_error) if (enumerable && !local_error)
{ {
result->next = g_thread_all_threads; result->next = g_thread_all_threads;
g_thread_all_threads = result; g_thread_all_threads = result;
@ -1308,9 +1325,9 @@ g_thread_exit (gpointer retval)
* Returns: the return value of the thread * Returns: the return value of the thread
*/ */
gpointer gpointer
g_thread_join (GThread* thread) g_thread_join (GThread *thread)
{ {
GRealThread* real = (GRealThread*) thread; GRealThread *real = (GRealThread*) thread;
GRealThread *p, *t; GRealThread *p, *t;
gpointer retval; gpointer retval;
@ -1322,19 +1339,22 @@ g_thread_join (GThread* thread)
retval = real->retval; retval = real->retval;
G_LOCK (g_thread); if (real->enumerable)
for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
{ {
if (t == (GRealThread*) thread) G_LOCK (g_thread);
for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
{ {
if (p) if (t == real)
p->next = t->next; {
else if (p)
g_thread_all_threads = t->next; p->next = t->next;
break; else
g_thread_all_threads = t->next;
break;
}
} }
G_UNLOCK (g_thread);
} }
G_UNLOCK (g_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;
g_system_thread_assign (real->system_thread, zero_thread); g_system_thread_assign (real->system_thread, zero_thread);
@ -1372,15 +1392,11 @@ g_thread_self (void)
thread->thread.func = NULL; thread->thread.func = NULL;
thread->thread.data = NULL; thread->thread.data = NULL;
thread->private_data = NULL; thread->private_data = NULL;
thread->enumerable = FALSE;
g_system_thread_self (&thread->system_thread); g_system_thread_self (&thread->system_thread);
g_private_set (&g_thread_specific_private, thread); g_private_set (&g_thread_specific_private, thread);
G_LOCK (g_thread);
thread->next = g_thread_all_threads;
g_thread_all_threads = thread;
G_UNLOCK (g_thread);
} }
return (GThread*)thread; return (GThread*)thread;

View File

@ -48,6 +48,14 @@ G_GNUC_INTERNAL gboolean g_system_thread_equal (gpointer thread1,
G_GNUC_INTERNAL void g_system_thread_exit (void); G_GNUC_INTERNAL void g_system_thread_exit (void);
G_GNUC_INTERNAL void g_system_thread_set_name (const gchar *name); G_GNUC_INTERNAL void g_system_thread_set_name (const gchar *name);
G_GNUC_INTERNAL GThread *g_thread_new_internal (const gchar *name,
GThreadFunc func,
gpointer data,
gboolean joinable,
gsize stack_size,
gboolean enumerable,
GError **error);
G_GNUC_INTERNAL GSystemThread zero_thread; G_GNUC_INTERNAL GSystemThread zero_thread;
G_GNUC_INTERNAL GMutex g_once_mutex; G_GNUC_INTERNAL GMutex g_once_mutex;