[glib] GActionGroupExporter: flush queue on requests



commit 865ce79ce0e92326b247ef51e7e2c78aaad99889
Author: Ryan Lortie <desrt desrt ca>
Date:   Thu May 21 12:32:20 2015 -0500

    GActionGroupExporter: flush queue on requests
    
    In order to maintain a logical stream of events, we need to make sure we
    flush and queued change notifications before responding to any requests
    for information from clients.
    
    If we don't do this, it's possible that we emit an 'add' event that was
    queued at the time of a 'DescribeAll' call _after_ the reply to that
    call (which already contained the description of the new action).
    
    In practice, this is not only logically incorrect, but it can also cause
    problems.  If a change to action 'state' or 'enabled' occurs after the
    DescribeAll but before the signal has been dispatched, it will be
    ignored because an 'add' signal is already pending.  When that add
    signal is sent, it will contain the correct data, but the receiver will
    ignore it because it already saw the action in the DescribeAll reply.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=749693

 gio/gactiongroupexporter.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)
---
diff --git a/gio/gactiongroupexporter.c b/gio/gactiongroupexporter.c
index 17a05fa..b68538c 100644
--- a/gio/gactiongroupexporter.c
+++ b/gio/gactiongroupexporter.c
@@ -208,6 +208,17 @@ g_action_group_exporter_dispatch_events (gpointer user_data)
   return FALSE;
 }
 
+static void
+g_action_group_exporter_flush_queue (GActionGroupExporter *exporter)
+{
+  if (exporter->pending_source)
+    {
+      g_source_destroy (exporter->pending_source);
+      g_action_group_exporter_dispatch_events (exporter);
+      g_assert (exporter->pending_source == NULL);
+    }
+}
+
 static guint
 g_action_group_exporter_get_events (GActionGroupExporter *exporter,
                                     const gchar          *name)
@@ -365,6 +376,8 @@ org_gtk_Actions_method_call (GDBusConnection       *connection,
   GActionGroupExporter *exporter = user_data;
   GVariant *result = NULL;
 
+  g_action_group_exporter_flush_queue (exporter);
+
   if (g_str_equal (method_name, "List"))
     {
       gchar **list;


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