[glib] gmain: improve g_source_set_name thread safety



commit dceff8fc2c354b994793d8792455bee7ed195169
Author: Ryan Lortie <desrt desrt ca>
Date:   Tue Sep 16 19:48:06 2014 -0400

    gmain: improve g_source_set_name thread safety
    
    Step up thread safety on g_source_set_name() to the same standard as all
    other GSource functions: after we are attached to a main context, this
    function should be threadsafe.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=736683

 glib/gmain.c |   23 +++++++++++++++++++----
 1 files changed, 19 insertions(+), 4 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index a6c8aef..30fac70 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -1854,17 +1854,29 @@ g_source_get_can_recurse (GSource  *source)
  *
  * It is permitted to call this function multiple times, but is not
  * recommended due to the potential performance impact.  For example,
- * one could change the name in the "check" function of a #GSourceFuncs 
+ * one could change the name in the "check" function of a #GSourceFuncs
  * to include details like the event type in the source name.
  *
+ * Use caution if changing the name while another thread may be
+ * accessing it with g_source_get_name(); that function does not copy
+ * the value, and changing the value will free it while the other thread
+ * may be attempting to use it.
+ *
  * Since: 2.26
  **/
 void
 g_source_set_name (GSource    *source,
                    const char *name)
 {
+  GMainContext *context;
+
   g_return_if_fail (source != NULL);
 
+  context = source->context;
+
+  if (context)
+    LOCK_CONTEXT (context);
+
   /* setting back to NULL is allowed, just because it's
    * weird if get_name can return NULL but you can't
    * set that.
@@ -1872,17 +1884,20 @@ g_source_set_name (GSource    *source,
 
   g_free (source->name);
   source->name = g_strdup (name);
+
+  if (context)
+    UNLOCK_CONTEXT (context);
 }
 
 /**
  * g_source_get_name:
  * @source: a #GSource
  *
- * Gets a name for the source, used in debugging and profiling.
- * The name may be #NULL if it has never been set with
- * g_source_set_name().
+ * Gets a name for the source, used in debugging and profiling.  The
+ * name may be #NULL if it has never been set with g_source_set_name().
  *
  * Returns: the name of the source
+ *
  * Since: 2.26
  **/
 const char *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]