[glib/wip/notify-performance: 7/8] [notify] add 'conditional' to _notify_queue_freeze



commit ddc8c0a1f9157e1df5cf1fc89d58cfb74022e368
Author: Ryan Lortie <desrt desrt ca>
Date:   Wed Nov 16 12:54:38 2011 +0000

    [notify] add 'conditional' to _notify_queue_freeze
    
    When the 'conditional' parameter is TRUE, the queue will only be frozen
    (ie: have its freeze count increase by one) if it is already frozen.
    
    This will allow us to avoid a freeze-notify-thaw in the case that we
    just want to notify on a single property.
    
    Another approach may have been to add an is_frozen() type call and avoid
    even increasing the freeze count at all in this case.  Unfortunately,
    I'm not totally sure what is the exact expected semantics of
    simultaneous notifications in multiple threads and this may interact
    badly with someone freezing or thawing in between our check and
    emission.

 gobject/gobject.c            |   16 ++++++++--------
 gobject/gobjectnotifyqueue.c |    9 ++++++++-
 2 files changed, 16 insertions(+), 9 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 7006a50..f2a959c 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -822,7 +822,7 @@ g_object_init (GObject		*object,
   if (CLASS_HAS_PROPS (class))
     {
       /* freeze object's notification queue, g_object_newv() preserves pairedness */
-      g_object_notify_queue_freeze (object);
+      g_object_notify_queue_freeze (object, FALSE);
     }
 
   if (CLASS_HAS_CUSTOM_CONSTRUCTOR (class))
@@ -952,7 +952,7 @@ g_object_freeze_notify (GObject *object)
     return;
 
   g_object_ref (object);
-  g_object_notify_queue_freeze (object);
+  g_object_notify_queue_freeze (object, FALSE);
   g_object_unref (object);
 }
 
@@ -985,7 +985,7 @@ g_object_notify_by_spec_internal (GObject    *object,
 
   if (notify_pspec != NULL)
     {
-      nqueue = g_object_notify_queue_freeze (object);
+      nqueue = g_object_notify_queue_freeze (object, FALSE);
       g_object_notify_queue_add (object, nqueue, notify_pspec);
       g_object_notify_queue_thaw (object, nqueue);
     }
@@ -1116,7 +1116,7 @@ g_object_thaw_notify (GObject *object)
   /* FIXME: Freezing is the only way to get at the notify queue.
    * So we freeze once and then thaw twice.
    */
-  nqueue = g_object_notify_queue_freeze (object);
+  nqueue = g_object_notify_queue_freeze (object, FALSE);
   g_object_notify_queue_thaw (object, nqueue);
   g_object_notify_queue_thaw (object, nqueue);
 
@@ -1525,7 +1525,7 @@ g_object_newv (GType       object_type,
   if (CLASS_HAS_PROPS (class))
     {
       if (newly_constructed || n_oparams)
-	nqueue = g_object_notify_queue_freeze (object);
+	nqueue = g_object_notify_queue_freeze (object, FALSE);
       if (newly_constructed)
 	g_object_notify_queue_thaw (object, nqueue);
     }
@@ -1645,7 +1645,7 @@ g_object_constructor (GType                  type,
   /* set construction parameters */
   if (n_construct_properties)
     {
-      GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (object);
+      GObjectNotifyQueue *nqueue = g_object_notify_queue_freeze (object, FALSE);
       
       /* set construct properties */
       while (n_construct_properties--)
@@ -1692,7 +1692,7 @@ g_object_set_valist (GObject	 *object,
   g_return_if_fail (G_IS_OBJECT (object));
   
   g_object_ref (object);
-  nqueue = g_object_notify_queue_freeze (object);
+  nqueue = g_object_notify_queue_freeze (object, FALSE);
   
   name = first_property_name;
   while (name)
@@ -1920,7 +1920,7 @@ g_object_set_property (GObject	    *object,
   g_return_if_fail (G_IS_VALUE (value));
   
   g_object_ref (object);
-  nqueue = g_object_notify_queue_freeze (object);
+  nqueue = g_object_notify_queue_freeze (object, FALSE);
   
   pspec = g_param_spec_pool_lookup (pspec_pool,
 				    property_name,
diff --git a/gobject/gobjectnotifyqueue.c b/gobject/gobjectnotifyqueue.c
index d6783ab..45f31f0 100644
--- a/gobject/gobjectnotifyqueue.c
+++ b/gobject/gobjectnotifyqueue.c
@@ -50,7 +50,8 @@ g_object_notify_queue_free (gpointer data)
 }
 
 static inline GObjectNotifyQueue*
-g_object_notify_queue_freeze (GObject *object)
+g_object_notify_queue_freeze (GObject  *object,
+                              gboolean  conditional)
 {
   GObjectNotifyQueue *nqueue;
 
@@ -58,6 +59,12 @@ g_object_notify_queue_freeze (GObject *object)
   nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue);
   if (!nqueue)
     {
+      if (conditional)
+        {
+          G_UNLOCK(notify_lock);
+          return NULL;
+        }
+
       nqueue = g_slice_new0 (GObjectNotifyQueue);
       g_datalist_id_set_data_full (&object->qdata, quark_notify_queue,
 				   nqueue, g_object_notify_queue_free);



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