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;
}; };
@ -1101,6 +1102,8 @@ g_thread_cleanup (gpointer data)
* If it is, the structure is freed in g_thread_join() * If it is, the structure is freed in g_thread_join()
*/ */
if (!thread->thread.joinable) if (!thread->thread.joinable)
{
if (thread->enumerable)
{ {
GRealThread *t, *p; GRealThread *t, *p;
@ -1117,6 +1120,7 @@ g_thread_cleanup (gpointer data)
} }
} }
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);
} }
/** /**
@ -1231,6 +1235,18 @@ g_thread_new_full (const gchar *name,
gboolean joinable, gboolean joinable,
gsize stack_size, gsize stack_size,
GError **error) GError **error)
{
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; GRealThread *result;
GError *local_error = NULL; GError *local_error = 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;
@ -1322,10 +1339,12 @@ g_thread_join (GThread* thread)
retval = real->retval; retval = real->retval;
if (real->enumerable)
{
G_LOCK (g_thread); G_LOCK (g_thread);
for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next) for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
{ {
if (t == (GRealThread*) thread) if (t == real)
{ {
if (p) if (p)
p->next = t->next; p->next = t->next;
@ -1335,6 +1354,7 @@ g_thread_join (GThread* thread)
} }
} }
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;