mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
GThread: handle thread names safely
Avoid a race condition where the string may be freed before the new thread got around to using it. Also add a test for thread names. https://bugzilla.gnome.org/show_bug.cgi?id=663381
This commit is contained in:
parent
375015018b
commit
7c0ee79e34
@ -57,6 +57,7 @@
|
||||
#endif /* G_OS_WIN32 */
|
||||
|
||||
#include "gslice.h"
|
||||
#include "gstrfuncs.h"
|
||||
#include "gtestutils.h"
|
||||
|
||||
/**
|
||||
@ -781,9 +782,6 @@ g_thread_proxy (gpointer data)
|
||||
|
||||
g_assert (data);
|
||||
|
||||
if (thread->name)
|
||||
g_system_thread_set_name (thread->name);
|
||||
|
||||
/* This has to happen before G_LOCK, as that might call g_thread_self */
|
||||
g_private_set (&g_thread_specific_private, data);
|
||||
|
||||
@ -793,6 +791,13 @@ g_thread_proxy (gpointer data)
|
||||
G_LOCK (g_thread_new);
|
||||
G_UNLOCK (g_thread_new);
|
||||
|
||||
if (thread->name)
|
||||
{
|
||||
g_system_thread_set_name (thread->name);
|
||||
g_free (thread->name);
|
||||
thread->name = NULL;
|
||||
}
|
||||
|
||||
thread->retval = thread->thread.func (thread->thread.data);
|
||||
|
||||
return NULL;
|
||||
@ -886,7 +891,7 @@ g_thread_new_internal (const gchar *name,
|
||||
thread->thread.joinable = TRUE;
|
||||
thread->thread.func = func;
|
||||
thread->thread.data = data;
|
||||
thread->name = name;
|
||||
thread->name = g_strdup (name);
|
||||
}
|
||||
G_UNLOCK (g_thread_new);
|
||||
|
||||
|
@ -32,7 +32,7 @@ struct _GRealThread
|
||||
|
||||
gint ref_count;
|
||||
gboolean ours;
|
||||
const gchar *name;
|
||||
gchar *name;
|
||||
gpointer retval;
|
||||
};
|
||||
|
||||
|
@ -29,6 +29,10 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -160,6 +164,29 @@ test_thread5 (void)
|
||||
g_thread_unref (thread);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
thread6_func (gpointer data)
|
||||
{
|
||||
const gchar name[16];
|
||||
|
||||
#ifdef HAVE_SYS_PRCTL_H
|
||||
prctl (PR_GET_NAME, name, 0, 0, 0, 0);
|
||||
|
||||
g_assert_cmpstr (name, ==, (gchar*)data);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
test_thread6 (void)
|
||||
{
|
||||
GThread *thread;
|
||||
|
||||
thread = g_thread_new ("abc", thread6_func, "abc");
|
||||
g_thread_join (thread);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -170,6 +197,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/thread/thread3", test_thread3);
|
||||
g_test_add_func ("/thread/thread4", test_thread4);
|
||||
g_test_add_func ("/thread/thread5", test_thread5);
|
||||
g_test_add_func ("/thread/thread6", test_thread6);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user