[glib/g-property: 8/14] gproperty: Fix locking



commit 6c8da2cb04832232d8459eea4ece12df480f67f0
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Thu Jun 2 13:42:21 2011 +0100

    gproperty: Fix locking
    
    Some cut-and-paste errors made atomic properties deadlock or just not
    work.

 gobject/gproperty.c            |  129 ++++++++++++++++++++++++++--------------
 gobject/tests/autoproperties.c |    2 +-
 2 files changed, 86 insertions(+), 45 deletions(-)
---
diff --git a/gobject/gproperty.c b/gobject/gproperty.c
index d0fa053..69d5500 100644
--- a/gobject/gproperty.c
+++ b/gobject/gproperty.c
@@ -642,29 +642,35 @@ g_##g_t##_property_set_value (GProperty *property, \
       return FALSE; \
     } \
 \
-  property_lock_internal (property, gobject); \
-\
   if (((G##G_t##Property *) property)->setter != NULL) \
     { \
+      property_lock_internal (property, gobject); \
+\
       ((G##G_t##Property *) property)->setter (gobject, value); \
 \
+      property_unlock_internal (property, gobject); \
+\
       retval = TRUE; \
     } \
   else if (property->field_offset >= 0) \
     { \
       gpointer priv_p, field_p; \
 \
+      property_lock_internal (property, gobject); \
+\
       priv_p = get_private_pointer (gobject, property->priv_offset); \
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset); \
 \
       if ((* (c_t *) field_p) == value) \
         { \
-          g_property_unlock (property, gobject); \
+          property_unlock_internal (property, gobject); \
           return FALSE; \
         } \
 \
       (* (c_t *) field_p) = value; \
 \
+      property_unlock_internal (property, gobject); \
+\
       g_object_notify_by_pspec (gobject, (GParamSpec *) property); \
 \
       retval = TRUE; \
@@ -678,8 +684,6 @@ g_##g_t##_property_set_value (GProperty *property, \
       retval = FALSE; \
     } \
 \
-  g_property_unlock (property, gobject); \
-\
   return retval; \
 } \
 \
@@ -727,7 +731,7 @@ g_property_default_lock (GProperty *property,
   if (bit_lock_p == NULL)
     {
       bit_lock_p = g_new0 (gint, 1);
-      g_object_set_qdata (gobject, property->prop_id, bit_lock_p);
+      g_object_set_qdata_full (gobject, property->prop_id, bit_lock_p, g_free);
     }
 
   g_bit_lock (bit_lock_p, 0);
@@ -740,12 +744,11 @@ g_property_default_unlock (GProperty *property,
   gpointer bit_lock_p;
 
   bit_lock_p = g_object_get_qdata (gobject, property->prop_id);
-  if (G_UNLIKELY (bit_lock_p == NULL))
+  if (bit_lock_p == NULL)
     return;
 
-  g_object_set_qdata (gobject, property->prop_id, NULL);
   g_bit_unlock (bit_lock_p, 0);
-  g_free (bit_lock_p);
+  g_object_set_qdata (gobject, property->prop_id, NULL);
 }
 
 static inline void
@@ -1310,29 +1313,35 @@ g_enum_property_set_value (GProperty *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GEnumProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GEnumProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   else if (property->field_offset >= 0)
     {
       gpointer priv_p, field_p;
 
+      property_lock_internal (property, gobject);
+
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
 
       if ((* (gulong *) field_p) == value)
         {
-          g_property_unlock (property, gobject);
+          property_unlock_internal (property, gobject);
           return FALSE;
         }
 
       (* (gulong *) field_p) = value;
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -1342,8 +1351,6 @@ g_enum_property_set_value (GProperty *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  g_property_unlock (property, gobject);
-
   return retval;
 }
 
@@ -1563,29 +1570,35 @@ g_flags_property_set_value (GProperty *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GFlagsProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GFlagsProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   else if (property->field_offset >= 0)
     {
       gpointer priv_p, field_p;
 
+      property_lock_internal (property, gobject);
+
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
 
       if ((* (gulong *) field_p) == value)
         {
-          g_property_unlock (property, gobject);
+          property_unlock_internal (property, gobject);
           return FALSE;
         }
 
       (* (gulong *) field_p) = value;
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -1595,8 +1608,6 @@ g_flags_property_set_value (GProperty *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  g_property_unlock (property, gobject);
-
   return retval;
 }
 
@@ -1836,18 +1847,22 @@ g_float_property_set_value (GProperty *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GFloatProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GFloatProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   else if (property->field_offset >= 0)
     {
       gpointer priv_p, field_p;
 
+      property_lock_internal (property, gobject);
+
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
 
@@ -1859,6 +1874,8 @@ g_float_property_set_value (GProperty *property,
 
       (* (gfloat *) field_p) = value;
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -1868,8 +1885,6 @@ g_float_property_set_value (GProperty *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  property_unlock_internal (property, gobject);
-
   return retval;
 }
 
@@ -2109,18 +2124,22 @@ g_double_property_set_value (GProperty *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GDoubleProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GDoubleProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   else if (property->field_offset >= 0)
     {
       gpointer priv_p, field_p;
 
+      property_lock_internal (property, gobject);
+
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
 
@@ -2132,6 +2151,8 @@ g_double_property_set_value (GProperty *property,
 
       (* (gdouble *) field_p) = value;
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -2141,8 +2162,6 @@ g_double_property_set_value (GProperty *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  property_unlock_internal (property, gobject);
-
   return retval;
 }
 
@@ -2309,12 +2328,14 @@ g_string_property_set_value (GProperty   *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GStringProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GStringProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   else if (property->field_offset >= 0)
@@ -2322,6 +2343,8 @@ g_string_property_set_value (GProperty   *property,
       gpointer priv_p, field_p;
       gchar *str;
 
+      property_lock_internal (property, gobject);
+
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
 
@@ -2336,6 +2359,8 @@ g_string_property_set_value (GProperty   *property,
       g_free (str);
       (* (gpointer *) field_p) = g_strdup (value);
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -2345,8 +2370,6 @@ g_string_property_set_value (GProperty   *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  property_unlock_internal (property, gobject);
-
   return retval;
 }
 
@@ -2519,18 +2542,22 @@ g_boxed_property_set_value (GProperty     *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GBoxedProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GBoxedProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   if (property->field_offset >= 0)
     {
       gpointer priv_p, field_p;
 
+      property_lock_internal (property, gobject);
+
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
 
@@ -2548,6 +2575,8 @@ g_boxed_property_set_value (GProperty     *property,
       else
         (* (gpointer *) field_p) = NULL;
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -2557,8 +2586,6 @@ g_boxed_property_set_value (GProperty     *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  property_unlock_internal (property, gobject);
-
   return retval;
 }
 
@@ -2731,12 +2758,14 @@ g_object_property_set_value (GProperty *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GObjectProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GObjectProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   else if (property->field_offset >= 0)
@@ -2746,6 +2775,8 @@ g_object_property_set_value (GProperty *property,
 
       g_return_val_if_fail (value == NULL || G_IS_OBJECT (value), FALSE);
 
+      property_lock_internal (property, gobject);
+
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
 
@@ -2769,6 +2800,8 @@ g_object_property_set_value (GProperty *property,
             g_object_ref (obj);
         }
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -2778,8 +2811,6 @@ g_object_property_set_value (GProperty *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  property_unlock_internal (property, gobject);
-
   return retval;
 }
 
@@ -2946,19 +2977,21 @@ g_pointer_property_set_value (GProperty *property,
       return FALSE;
     }
 
-  property_lock_internal (property, gobject);
-
   if (((GPointerProperty *) property)->setter != NULL)
     {
+      property_lock_internal (property, gobject);
+
       ((GPointerProperty *) property)->setter (gobject, value);
 
+      property_unlock_internal (property, gobject);
+
       retval = TRUE;
     }
   else if (property->field_offset >= 0)
     {
       gpointer priv_p, field_p;
 
-      g_return_val_if_fail (value == NULL || G_IS_OBJECT (value), FALSE);
+      property_lock_internal (property, gobject);
 
       priv_p = get_private_pointer (gobject, property->priv_offset);
       field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset);
@@ -2971,6 +3004,8 @@ g_pointer_property_set_value (GProperty *property,
 
       (* (gpointer *) field_p) = value;
 
+      property_unlock_internal (property, gobject);
+
       g_object_notify_by_pspec (gobject, (GParamSpec *) property);
 
       retval = TRUE;
@@ -2980,8 +3015,6 @@ g_pointer_property_set_value (GProperty *property,
                 "for property '%s'",
                 G_PARAM_SPEC (property)->name);
 
-  property_unlock_internal (property, gobject);
-
   return retval;
 }
 
@@ -4163,6 +4196,8 @@ g_property_set_valist (GProperty *property,
   g_return_val_if_fail (G_IS_OBJECT (gobject), FALSE);
   g_return_val_if_fail (property->is_installed, FALSE);
 
+  g_object_ref (gobject);
+
   gtype = G_PARAM_SPEC (property)->value_type;
 
   switch (G_TYPE_FUNDAMENTAL (gtype))
@@ -4267,6 +4302,8 @@ g_property_set_valist (GProperty *property,
       break;
     }
 
+  g_object_unref (gobject);
+
   return retval;
 }
 
@@ -4932,6 +4969,8 @@ g_property_set_value (GProperty    *property,
       return;
     }
 
+  g_object_ref (gobject);
+
   switch (G_TYPE_FUNDAMENTAL (gtype))
     {
     case G_TYPE_BOOLEAN:
@@ -5041,6 +5080,8 @@ g_property_set_value (GProperty    *property,
       break;
     }
 
+  g_object_unref (gobject);
+
   g_value_unset (&copy);
 }
 
diff --git a/gobject/tests/autoproperties.c b/gobject/tests/autoproperties.c
index 62f7a8a..7eac768 100644
--- a/gobject/tests/autoproperties.c
+++ b/gobject/tests/autoproperties.c
@@ -222,7 +222,7 @@ test_object_class_init (TestObjectClass *klass)
   g_property_set_default (G_PROPERTY (test_object_properties[PROP_FOO]), 50);
 
   test_object_properties[PROP_BAR] =
-    g_boolean_property_new ("bar", G_PROPERTY_READWRITE | G_PROPERTY_ATOMIC,
+    g_boolean_property_new ("bar", G_PROPERTY_READWRITE,
                             G_STRUCT_OFFSET (TestObjectPrivate, bar),
                             NULL, NULL);
 



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