Bug 632544 – Cannot send a locked message with PRESERVE_SERIAL flag
[platform/upstream/glib.git] / gio / gdbusconnection.c
index 375ca3c..809f976 100644 (file)
@@ -1026,10 +1026,7 @@ flush_in_thread_func (GSimpleAsyncResult *res,
   if (!g_dbus_connection_flush_sync (G_DBUS_CONNECTION (object),
                                      cancellable,
                                      &error))
-    {
-      g_simple_async_result_set_from_error (res, error);
-      g_error_free (error);
-    }
+    g_simple_async_result_take_error (res, error);
 }
 
 /**
@@ -1237,10 +1234,7 @@ close_in_thread_func (GSimpleAsyncResult *res,
   if (!g_dbus_connection_close_sync (G_DBUS_CONNECTION (object),
                                      cancellable,
                                      &error))
-    {
-      g_simple_async_result_set_from_error (res, error);
-      g_error_free (error);
-    }
+    g_simple_async_result_take_error (res, error);
 }
 
 /**
@@ -1458,7 +1452,8 @@ g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
   if (out_serial != NULL)
     *out_serial = serial_to_use;
 
-  g_dbus_message_set_serial (message, serial_to_use);
+  if (!(flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL))
+    g_dbus_message_set_serial (message, serial_to_use);
 
   g_dbus_message_lock (message);
   _g_dbus_worker_send_message (connection->worker,
@@ -1748,7 +1743,7 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection     *connect
   error = NULL;
   if (!g_dbus_connection_send_message_unlocked (connection, message, flags, out_serial, &error))
     {
-      g_simple_async_result_set_from_error (simple, error);
+      g_simple_async_result_take_error (simple, error);
       g_simple_async_result_complete_in_idle (simple);
       g_object_unref (simple);
       goto out;
@@ -2983,11 +2978,14 @@ args_to_rule (const gchar *sender,
               const gchar *interface_name,
               const gchar *member,
               const gchar *object_path,
-              const gchar *arg0)
+              const gchar *arg0,
+              gboolean     negate)
 {
   GString *rule;
 
   rule = g_string_new ("type='signal'");
+  if (negate)
+    g_string_prepend_c (rule, '-');
   if (sender != NULL)
     g_string_append_printf (rule, ",sender='%s'", sender);
   if (interface_name != NULL)
@@ -3016,6 +3014,9 @@ add_match_rule (GDBusConnection *connection,
   GError *error;
   GDBusMessage *message;
 
+  if (match_rule[0] == '-')
+    return;
+
   message = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
                                             "/org/freedesktop/DBus", /* path */
                                             "org.freedesktop.DBus", /* interface */
@@ -3044,6 +3045,9 @@ remove_match_rule (GDBusConnection *connection,
   GError *error;
   GDBusMessage *message;
 
+  if (match_rule[0] == '-')
+    return;
+
   message = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
                                             "/org/freedesktop/DBus", /* path */
                                             "org.freedesktop.DBus", /* interface */
@@ -3147,7 +3151,16 @@ g_dbus_connection_signal_subscribe (GDBusConnection     *connection,
 
   CONNECTION_LOCK (connection);
 
-  rule = args_to_rule (sender, interface_name, member, object_path, arg0);
+  /* If G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE was specified, we will end up
+   * with a '-' character to prefix the rule (which will otherwise be
+   * normal).
+   *
+   * This allows us to hash the rule and do our lifecycle tracking in
+   * the usual way, but the '-' prevents the match rule from ever
+   * actually being send to the bus (either for add or remove).
+   */
+  rule = args_to_rule (sender, interface_name, member, object_path, arg0,
+                       (flags & G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE) != 0);
 
   if (sender != NULL && (g_dbus_is_unique_name (sender) || g_strcmp0 (sender, "org.freedesktop.DBus") == 0))
     sender_unique_name = sender;
@@ -4974,10 +4987,7 @@ g_dbus_connection_call_done (GObject      *source,
     value = NULL;
 
   if (value == NULL)
-    {
-      g_simple_async_result_set_from_error (state->simple, error);
-      g_error_free (error);
-    }
+    g_simple_async_result_take_error (state->simple, error);
   else
     g_simple_async_result_set_op_res_gpointer (state->simple, value,
                                                (GDestroyNotify) g_variant_unref);
@@ -6284,8 +6294,7 @@ bus_get_async_initable_cb (GObject      *source_object,
                                      &error))
     {
       g_assert (error != NULL);
-      g_simple_async_result_set_from_error (simple, error);
-      g_error_free (error);
+      g_simple_async_result_take_error (simple, error);
       g_object_unref (source_object);
     }
   else
@@ -6335,8 +6344,7 @@ g_bus_get (GBusType             bus_type,
   if (connection == NULL)
     {
       g_assert (error != NULL);
-      g_simple_async_result_set_from_error (simple, error);
-      g_error_free (error);
+      g_simple_async_result_take_error (simple, error);
       g_simple_async_result_complete_in_idle (simple);
       g_object_unref (simple);
     }