[glib] GDBus: set no-reply flag on calls with no callback



commit 2afbc425eb24f21c598636e5037782cb8a1870ea
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Mar 16 13:32:38 2012 -0400

    GDBus: set no-reply flag on calls with no callback
    
    If g_dbus_connection_call() or g_dbus_proxy_call() are given a NULL
    callback then set the no-reply flag on the outgoing D-Bus message.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=672239

 gio/gdbusconnection.c |   71 +++++++++++++++++++++++++++++++++---------------
 gio/gdbusproxy.c      |   46 ++++++++++++++++++++++---------
 2 files changed, 82 insertions(+), 35 deletions(-)
---
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index a0e55b4..5f85e40 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -5309,7 +5309,7 @@ g_dbus_connection_call_internal (GDBusConnection        *connection,
                                  gpointer                user_data)
 {
   GDBusMessage *message;
-  CallState *state;
+  guint32 serial;
 
   g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
   g_return_if_fail (bus_name == NULL || g_dbus_is_name (bus_name));
@@ -5325,18 +5325,6 @@ g_dbus_connection_call_internal (GDBusConnection        *connection,
   g_return_if_fail (fd_list == NULL);
 #endif
 
-  state = g_slice_new0 (CallState);
-  state->simple = g_simple_async_result_new (G_OBJECT (connection),
-                                             callback, user_data,
-                                             g_dbus_connection_call_internal);
-  g_simple_async_result_set_check_cancellable (state->simple, cancellable);
-  state->method_name = g_strjoin (".", interface_name, method_name, NULL);
-
-  if (reply_type == NULL)
-    reply_type = G_VARIANT_TYPE_ANY;
-
-  state->reply_type = g_variant_type_copy (reply_type);
-
   message = g_dbus_message_new_method_call (bus_name,
                                             object_path,
                                             interface_name,
@@ -5350,14 +5338,50 @@ g_dbus_connection_call_internal (GDBusConnection        *connection,
     g_dbus_message_set_unix_fd_list (message, fd_list);
 #endif
 
-  g_dbus_connection_send_message_with_reply (connection,
-                                             message,
-                                             G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-                                             timeout_msec,
-                                             &state->serial,
-                                             cancellable,
-                                             g_dbus_connection_call_done,
-                                             state);
+  /* If the user has no callback then we can just send the message with
+   * the G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED flag set and skip all
+   * the logic for processing the reply.  If the service sends the reply
+   * anyway then it will just be ignored.
+   */
+  if (callback != NULL)
+    {
+      CallState *state;
+
+      state = g_slice_new0 (CallState);
+      state->simple = g_simple_async_result_new (G_OBJECT (connection),
+                                                 callback, user_data,
+                                                 g_dbus_connection_call_internal);
+      g_simple_async_result_set_check_cancellable (state->simple, cancellable);
+      state->method_name = g_strjoin (".", interface_name, method_name, NULL);
+
+      if (reply_type == NULL)
+        reply_type = G_VARIANT_TYPE_ANY;
+
+      state->reply_type = g_variant_type_copy (reply_type);
+
+      g_dbus_connection_send_message_with_reply (connection,
+                                                 message,
+                                                 G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+                                                 timeout_msec,
+                                                 &state->serial,
+                                                 cancellable,
+                                                 g_dbus_connection_call_done,
+                                                 state);
+      serial = state->serial;
+    }
+  else
+    {
+      GDBusMessageFlags flags;
+
+      flags = g_dbus_message_get_flags (message);
+      flags |= G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED;
+      g_dbus_message_set_flags (message, flags);
+
+      g_dbus_connection_send_message (connection,
+                                      message,
+                                      G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+                                      &serial, NULL);
+    }
 
   if (G_UNLIKELY (_g_dbus_debug_call ()))
     {
@@ -5371,7 +5395,7 @@ g_dbus_connection_call_internal (GDBusConnection        *connection,
                method_name,
                object_path,
                bus_name != NULL ? bus_name : "(none)",
-               state->serial);
+               serial);
       _g_dbus_debug_print_unlock ();
     }
 
@@ -5598,6 +5622,9 @@ g_dbus_connection_call_sync_internal (GDBusConnection         *connection,
  * See g_dbus_connection_call_sync() for the synchronous version of this
  * function.
  *
+ * If @callback is %NULL then the D-Bus method call message will be sent with
+ * the %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED flag set.
+ *
  * Since: 2.26
  */
 void
diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
index 398dcce..ed46935 100644
--- a/gio/gdbusproxy.c
+++ b/gio/gdbusproxy.c
@@ -2682,6 +2682,7 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
   const gchar *target_interface_name;
   gchar *destination;
   GVariantType *reply_type;
+  GAsyncReadyCallback my_callback;
 
   g_return_if_fail (G_IS_DBUS_PROXY (proxy));
   g_return_if_fail (g_dbus_is_member_name (method_name) || g_dbus_is_interface_name (method_name));
@@ -2696,11 +2697,24 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
   reply_type = NULL;
   split_interface_name = NULL;
 
-  simple = g_simple_async_result_new (G_OBJECT (proxy),
-                                      callback,
-                                      user_data,
-                                      g_dbus_proxy_call_internal);
-  g_simple_async_result_set_check_cancellable (simple, cancellable);
+  /* g_dbus_connection_call() is optimised for the case of a NULL
+   * callback.  If we get a NULL callback from our user then make sure
+   * we pass along a NULL callback for ourselves as well.
+   */
+  if (callback != NULL)
+    {
+      my_callback = (GAsyncReadyCallback) reply_cb;
+      simple = g_simple_async_result_new (G_OBJECT (proxy),
+                                          callback,
+                                          user_data,
+                                          g_dbus_proxy_call_internal);
+      g_simple_async_result_set_check_cancellable (simple, cancellable);
+    }
+  else
+    {
+      my_callback = NULL;
+      simple = NULL;
+    }
 
   G_LOCK (properties_lock);
 
@@ -2723,12 +2737,15 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
       destination = g_strdup (get_destination_for_call (proxy));
       if (destination == NULL)
         {
-          g_simple_async_result_set_error (simple,
-                                           G_IO_ERROR,
-                                           G_IO_ERROR_FAILED,
-                                           _("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
-          g_simple_async_result_complete_in_idle (simple);
-          g_object_unref (simple);
+          if (simple != NULL)
+            {
+              g_simple_async_result_set_error (simple,
+                                               G_IO_ERROR,
+                                               G_IO_ERROR_FAILED,
+                                               _("Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag"));
+              g_simple_async_result_complete_in_idle (simple);
+              g_object_unref (simple);
+            }
           G_UNLOCK (properties_lock);
           goto out;
         }
@@ -2748,7 +2765,7 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
                                             timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
                                             fd_list,
                                             cancellable,
-                                            (GAsyncReadyCallback) reply_cb,
+                                            my_callback,
                                             simple);
 #else
   g_dbus_connection_call (proxy->priv->connection,
@@ -2761,7 +2778,7 @@ g_dbus_proxy_call_internal (GDBusProxy          *proxy,
                           flags,
                           timeout_msec == -1 ? proxy->priv->timeout_msec : timeout_msec,
                           cancellable,
-                          (GAsyncReadyCallback) reply_cb,
+                          my_callback,
                           simple);
 #endif
 
@@ -2964,6 +2981,9 @@ g_dbus_proxy_call_sync_internal (GDBusProxy      *proxy,
  * the operation. See g_dbus_proxy_call_sync() for the synchronous
  * version of this method.
  *
+ * If @callback is %NULL then the D-Bus method call message will be sent with
+ * the %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED flag set.
+ *
  * Since: 2.26
  */
 void



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