[glib] GThread: handle thread names safely
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GThread: handle thread names safely
- Date: Tue, 15 Nov 2011 03:19:30 +0000 (UTC)
commit 7c0ee79e348cfa3711ecf74f1c0e4d9a2e29864e
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Nov 14 22:18:13 2011 -0500
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
glib/gthread.c | 13 +++++++++----
glib/gthreadprivate.h | 2 +-
glib/tests/thread.c | 28 ++++++++++++++++++++++++++++
3 files changed, 38 insertions(+), 5 deletions(-)
---
diff --git a/glib/gthread.c b/glib/gthread.c
index b17280f..d956308 100644
--- a/glib/gthread.c
+++ b/glib/gthread.c
@@ -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);
diff --git a/glib/gthreadprivate.h b/glib/gthreadprivate.h
index 3670b2f..6b974de 100644
--- a/glib/gthreadprivate.h
+++ b/glib/gthreadprivate.h
@@ -32,7 +32,7 @@ struct _GRealThread
gint ref_count;
gboolean ours;
- const gchar *name;
+ gchar *name;
gpointer retval;
};
diff --git a/glib/tests/thread.c b/glib/tests/thread.c
index a614c27..b6bb5a9 100644
--- a/glib/tests/thread.c
+++ b/glib/tests/thread.c
@@ -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 ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]