[glib/freeze-shenanigans: 3/4] freeze/thaw thuggery




commit 519363175a0bfcfd699eee22632955b393b43b7b
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jun 8 14:06:40 2022 -0400

    freeze/thaw thuggery

 gobject/gobject.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 1d9db7bb84..74016a2426 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -1441,24 +1441,48 @@ static inline void
 g_object_notify_by_spec_internal (GObject    *object,
                                   GParamSpec *pspec)
 {
+  guint object_flags;
+  gboolean has_notify;
+  gboolean in_init;
+
   if (G_UNLIKELY (~pspec->flags & G_PARAM_READABLE))
     return;
 
   param_spec_follow_override (&pspec);
 
-  if (pspec != NULL &&
-      _g_object_has_notify_handler (object))
+#ifdef HAVE_OPTIONAL_FLAGS
+  object_flags = object_get_optional_flags (object);
+  has_notify = ((object_flags & OPTIONAL_FLAG_HAS_NOTIFY_HANDLER) != 0) ||
+               CLASS_HAS_NOTIFY (G_OBJECT_GET_CLASS (object));
+  in_init = (object_flags & OPTIONAL_FLAG_IN_CONSTRUCTION) != 0;
+#else
+  has_notify = TRUE;
+  in_init = object_in_construction (object);
+#endif
+
+  if (pspec != NULL && has_notify)
     {
       GObjectNotifyQueue *nqueue;
+      gboolean need_thaw = TRUE;
 
       /* conditional freeze: only increase freeze count if already frozen */
       nqueue = g_object_notify_queue_freeze (object, TRUE);
+      if (in_init && !nqueue)
+        {
+          /* We did not freeze the queue in g_object_init, but
+           * we gained a notify handler in instance init, so
+           * now we need to freeze just-in-time
+           */
+          nqueue = g_object_notify_queue_freeze (object, FALSE);
+          need_thaw = FALSE;
+        }
 
       if (nqueue != NULL)
         {
           /* we're frozen, so add to the queue and release our freeze */
           g_object_notify_queue_add (object, nqueue, pspec);
-          g_object_notify_queue_thaw (object, nqueue);
+          if (need_thaw)
+            g_object_notify_queue_thaw (object, nqueue);
         }
       else
         {
@@ -2167,11 +2191,12 @@ g_object_new_internal (GObjectClass          *class,
     {
       GSList *node;
 
-      if (CLASS_HAS_NOTIFY (class))
+      if (_g_object_has_notify_handler (object))
         {
           /* This will have been setup in g_object_init() */
           nqueue = g_datalist_id_get_data (&object->qdata, quark_notify_queue);
-          g_assert (nqueue != NULL);
+          if (!nqueue)
+            nqueue = g_object_notify_queue_freeze (object, FALSE);
         }
 
       /* We will set exactly n_construct_properties construct


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