[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / gio / gdbusconnection.c
index 09b5598..ca09ae3 100644 (file)
 
 #ifdef G_OS_UNIX
 #include "gkdbus.h"
-#include "gkdbusconnection.h"
 #include "gunixconnection.h"
 #include "gunixfdmessage.h"
 #endif
@@ -391,6 +390,7 @@ struct _GDBusConnection
    * hold @init_lock or check for initialization first.
    */
   GDBusWorker *worker;
+  GKDBusWorker *kdbus_worker;
 
   /* If connected to a message bus, this contains the unique name assigned to
    * us by the bus (e.g. ":1.42").
@@ -1162,8 +1162,12 @@ g_dbus_connection_start_message_processing (GDBusConnection *connection)
   if (!check_initialized (connection))
     return;
 
-  g_assert (connection->worker != NULL);
-  _g_dbus_worker_unfreeze (connection->worker);
+  g_assert (connection->worker || connection->kdbus_worker);
+
+  if (connection->kdbus_worker)
+    g_kdbus_worker_unfreeze (connection->kdbus_worker);
+  else
+    _g_dbus_worker_unfreeze (connection->worker);
 }
 
 /**
@@ -1623,8 +1627,8 @@ g_dbus_request_name (GDBusConnection     *connection,
   g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), G_BUS_RELEASE_NAME_FLAGS_ERROR);
   g_return_val_if_fail (error == NULL || *error == NULL, G_BUS_RELEASE_NAME_FLAGS_ERROR);
 
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
-    result = _g_kdbus_RequestName (connection, name, flags, error);
+  if (connection->kdbus_worker)
+    result = _g_kdbus_RequestName (connection->kdbus_worker, name, flags, error);
   else
     result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
                                           "org.freedesktop.DBus", "RequestName",
@@ -1669,8 +1673,8 @@ g_dbus_release_name (GDBusConnection     *connection,
   g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), G_BUS_RELEASE_NAME_FLAGS_ERROR);
   g_return_val_if_fail (error == NULL || *error == NULL, G_BUS_RELEASE_NAME_FLAGS_ERROR);
 
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
-    result = _g_kdbus_ReleaseName (connection, name, error);
+  if (connection->kdbus_worker)
+    result = _g_kdbus_ReleaseName (connection->kdbus_worker, name, error);
   else
     result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/org/freedesktop/DBus",
                                           "org.freedesktop.DBus", "ReleaseName",
@@ -1715,9 +1719,9 @@ g_dbus_get_bus_id (GDBusConnection  *connection,
   result = NULL;
   bus_id = NULL;
 
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
+  if (connection->kdbus_worker)
     {
-      result = _g_kdbus_GetBusId (connection, error);
+      result = _g_kdbus_GetBusId (connection->kdbus_worker, error);
     }
   else
     {
@@ -1760,8 +1764,8 @@ _g_dbus_get_list_internal (GDBusConnection    *connection,
 
   if (list_name_type == LIST_QUEUED_OWNERS)
     {
-      if (G_IS_KDBUS_CONNECTION (connection->stream))
-        result = _g_kdbus_GetListQueuedOwners (connection, name, error);
+      if (connection->kdbus_worker)
+        result = _g_kdbus_GetListQueuedOwners (connection->kdbus_worker, name, error);
       else
         result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
                                               "org.freedesktop.DBus", "ListQueuedOwners",
@@ -1777,8 +1781,8 @@ _g_dbus_get_list_internal (GDBusConnection    *connection,
       else
         method_name = "ListActivatableNames";
 
-      if (G_IS_KDBUS_CONNECTION (connection->stream))
-        result = _g_kdbus_GetListNames (connection, list_name_type, error);
+      if (connection->kdbus_worker)
+        result = _g_kdbus_GetListNames (connection->kdbus_worker, list_name_type, error);
       else
         result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
                                               "org.freedesktop.DBus", method_name,
@@ -1934,8 +1938,8 @@ g_dbus_get_name_owner (GDBusConnection  *connection,
   name_owner = NULL;
   result = NULL;
 
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
-    result = _g_kdbus_GetNameOwner (connection, name, error);
+  if (connection->kdbus_worker)
+    result = _g_kdbus_GetNameOwner (connection->kdbus_worker, name, error);
   else
     result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
                                           "org.freedesktop.DBus", "GetNameOwner",
@@ -1953,57 +1957,6 @@ g_dbus_get_name_owner (GDBusConnection  *connection,
 }
 
 /**
- * g_dbus_name_has_owner:
- * @connection: a #GDBusConnection
- * @name: a unique or well-known bus name
- * @error: return location for error or %NULL
- *
- * Synchronously checks if the specified name exists (currently has an owner).
- *
- * If @name contains a value not compatible with the D-Bus syntax and naming
- * conventions for bus names, the operation returns %NULL and @error is set.
- *
- * The calling thread is blocked until a reply is received.
- *
- * Returns: %TRUE if specified name exists (currently has an owner)
- *     If the requested name doesn't have an owner or @error is set,
- *     function returns %FALSE.
- *
- * Since: 2.4x
- */
-gboolean
-g_dbus_name_has_owner (GDBusConnection  *connection,
-                       const gchar      *name,
-                       GError          **error)
-{
-  GVariant *result;
-  gboolean ret;
-
-  g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
-  g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL);
-  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
-  result = NULL;
-
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
-    result = _g_kdbus_NameHasOwner (connection, name, error);
-  else
-    result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
-                                          "org.freedesktop.DBus", "NameHasOwner",
-                                          g_variant_new ("(s)", name), G_VARIANT_TYPE ("(b)"),
-                                          G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
-  if (result != NULL)
-    {
-      g_variant_get (result, "(b)", &ret);
-      g_variant_unref (result);
-    }
-  else
-    ret = FALSE;
-
-  return ret;
-}
-
-/**
  * g_dbus_get_connection_pid:
  * @connection: a #GDBusConnection
  * @name: a unique or well-known bus name of the connection to query
@@ -2038,8 +1991,8 @@ g_dbus_get_connection_pid (GDBusConnection  *connection,
   result = NULL;
   pid = -1;
 
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
-    result = _g_kdbus_GetConnectionUnixProcessID (connection, name, error);
+  if (connection->kdbus_worker)
+    result = _g_kdbus_GetConnectionUnixProcessID (connection->kdbus_worker, name, error);
   else
     result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
                                           "org.freedesktop.DBus", "GetConnectionUnixProcessID",
@@ -2089,8 +2042,8 @@ g_dbus_get_connection_uid (GDBusConnection  *connection,
   result = NULL;
   uid = -1;
 
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
-    result = _g_kdbus_GetConnectionUnixUser (connection, name, error);
+  if (connection->kdbus_worker)
+    result = _g_kdbus_GetConnectionUnixUser (connection->kdbus_worker, name, error);
   else
     result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
                                           "org.freedesktop.DBus", "GetConnectionUnixUser",
@@ -2138,7 +2091,7 @@ g_dbus_connection_get_last_serial (GDBusConnection *connection)
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
-
+#include "gkdbus.h"
 /* Can be called by any thread, with the connection lock held */
 static gboolean
 g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
@@ -2179,13 +2132,16 @@ g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
                                  &blob_size,
                                  connection->capabilities,
                                  error);
+
   if (blob == NULL)
     goto out;
 
-  if (flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL)
-    serial_to_use = g_dbus_message_get_serial (message);
-  else
-    serial_to_use = ++connection->last_serial; /* TODO: handle overflow */
+  if (!(flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL))
+    g_dbus_message_set_serial (message, ++connection->last_serial);
+
+  serial_to_use = g_dbus_message_get_serial (message);
+
+  g_dbus_message_lock (message);
 
   switch (blob[0])
     {
@@ -2222,14 +2178,14 @@ g_dbus_connection_send_message_unlocked (GDBusConnection   *connection,
                         g_thread_self (),
                         GUINT_TO_POINTER (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);
+  if (connection->worker)
   _g_dbus_worker_send_message (connection->worker,
                                message,
                                (gchar*) blob,
                                blob_size);
+  else
+  g_kdbus_worker_send_message (connection->kdbus_worker, message, error);
+
   blob = NULL; /* since _g_dbus_worker_send_message() steals the blob */
 
   ret = TRUE;
@@ -2802,8 +2758,7 @@ typedef struct
 
 /* Called in GDBusWorker's thread - we must not block - with no lock held */
 static void
-on_worker_message_received (GDBusWorker  *worker,
-                            GDBusMessage *message,
+on_worker_message_received (GDBusMessage *message,
                             gpointer      user_data)
 {
   GDBusConnection *connection;
@@ -2904,8 +2859,7 @@ on_worker_message_received (GDBusWorker  *worker,
 
 /* Called in GDBusWorker's thread, lock is not held */
 static GDBusMessage *
-on_worker_message_about_to_be_sent (GDBusWorker  *worker,
-                                    GDBusMessage *message,
+on_worker_message_about_to_be_sent (GDBusMessage *message,
                                     gpointer      user_data)
 {
   GDBusConnection *connection;
@@ -2981,10 +2935,9 @@ cancel_method_on_close (gpointer key, gpointer value, gpointer user_data)
 
 /* Called in GDBusWorker's thread - we must not block - without lock held */
 static void
-on_worker_closed (GDBusWorker *worker,
-                  gboolean     remote_peer_vanished,
-                  GError      *error,
-                  gpointer     user_data)
+on_worker_closed (gboolean  remote_peer_vanished,
+                  GError   *error,
+                  gpointer  user_data)
 {
   GDBusConnection *connection;
   gboolean alive;
@@ -3046,6 +2999,7 @@ initable_init (GInitable     *initable,
                GError       **error)
 {
   GDBusConnection *connection = G_DBUS_CONNECTION (initable);
+  gboolean initially_frozen;
   gboolean ret;
 
   /* This method needs to be idempotent to work with the singleton
@@ -3083,6 +3037,8 @@ initable_init (GInitable     *initable,
    */
   if (connection->address != NULL)
     {
+      GObject *ret;
+
       g_assert (connection->stream == NULL);
 
       if ((connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER) ||
@@ -3095,12 +3051,18 @@ initable_init (GInitable     *initable,
           goto out;
         }
 
-      connection->stream = g_dbus_address_get_stream_sync (connection->address,
-                                                           NULL, /* TODO: out_guid */
-                                                           cancellable,
-                                                           &connection->initialization_error);
-      if (connection->stream == NULL)
+      ret = g_dbus_address_get_stream_internal (connection->address, TRUE,
+                                                NULL, /* TODO: out_guid */
+                                                cancellable, &connection->initialization_error);
+      if (ret == NULL)
         goto out;
+
+      if (G_IS_IO_STREAM (ret))
+        connection->stream = G_IO_STREAM (ret);
+      else if (G_IS_KDBUS_WORKER (ret))
+        connection->kdbus_worker = G_KDBUS_WORKER (ret);
+      else
+        g_assert_not_reached ();
     }
   else if (connection->stream != NULL)
     {
@@ -3112,7 +3074,7 @@ initable_init (GInitable     *initable,
     }
 
   /* [KDBUS] Skip authentication process for kdbus transport */
-  if (G_IS_KDBUS_CONNECTION (connection->stream))
+  if (connection->kdbus_worker)
     {
       goto authenticated;
     }
@@ -3177,13 +3139,23 @@ authenticated:
   g_hash_table_insert (alive_connections, connection, connection);
   G_UNLOCK (message_bus_lock);
 
-  connection->worker = _g_dbus_worker_new (connection->stream,
-                                           connection->capabilities,
-                                           ((connection->flags & G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) != 0),
-                                           on_worker_message_received,
-                                           on_worker_message_about_to_be_sent,
-                                           on_worker_closed,
-                                           connection);
+  initially_frozen = (connection->flags & G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING) != 0;
+
+  if (connection->kdbus_worker)
+   g_kdbus_worker_associate (connection->kdbus_worker,
+                             connection->capabilities,
+                             on_worker_message_received,
+                             on_worker_message_about_to_be_sent,
+                             on_worker_closed,
+                             connection);
+  else
+    connection->worker = _g_dbus_worker_new (connection->stream,
+                                             connection->capabilities,
+                                             initially_frozen,
+                                             on_worker_message_received,
+                                             on_worker_message_about_to_be_sent,
+                                             on_worker_closed,
+                                             connection);
 
   /* if a bus connection, call org.freedesktop.DBus.Hello - this is how we're getting a name */
   if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION)
@@ -3200,9 +3172,9 @@ authenticated:
           goto out;
         }
 
-      if (G_IS_KDBUS_CONNECTION (connection->stream))
+      if (connection->kdbus_worker)
         {
-          hello_result = _g_kdbus_Hello (connection->stream, &connection->initialization_error);
+          hello_result = _g_kdbus_Hello (connection->kdbus_worker, &connection->initialization_error);
         }
       else
         {
@@ -3227,6 +3199,9 @@ authenticated:
       //g_debug ("unique name is '%s'", connection->bus_unique_name);
     }
 
+  if (connection->kdbus_worker && !initially_frozen)
+    g_kdbus_worker_unfreeze (connection->kdbus_worker);
+
   ret = TRUE;
  out:
   if (!ret)
@@ -4083,15 +4058,18 @@ g_dbus_connection_signal_subscribe (GDBusConnection     *connection,
   if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION)
     {
       if (!is_signal_data_for_name_lost_or_acquired (signal_data))
-        add_match_rule (connection, signal_data->rule);
+        if (connection->kdbus_worker)
+          _g_kdbus_AddMatch (connection->kdbus_worker, signal_data->rule, subscriber.id);
+        else
+          add_match_rule (connection, signal_data->rule);
       else
         {
-          if (G_IS_KDBUS_CONNECTION (connection->stream))
+          if (connection->kdbus_worker)
             {
               if (g_strcmp0 (signal_data->member, "NameAcquired") == 0)
-                _g_kdbus_subscribe_name_acquired (connection, arg0);
+                _g_kdbus_subscribe_name_acquired (connection->kdbus_worker, arg0);
               else if (g_strcmp0 (signal_data->member, "NameLost") == 0)
-                _g_kdbus_subscribe_name_lost (connection, arg0);
+                _g_kdbus_subscribe_name_lost (connection->kdbus_worker, arg0);
             }
         }
     }
@@ -4178,16 +4156,19 @@ unsubscribe_id_internal (GDBusConnection *connection,
                * so on_worker_closed() can't happen between the check we just
                * did, and releasing the lock later.
                */
-              remove_match_rule (connection, signal_data->rule);
+              if (connection->kdbus_worker)
+                _g_kdbus_RemoveMatch (connection->kdbus_worker, subscription_id);
+              else
+                remove_match_rule (connection, signal_data->rule);
             }
           else
             {
-              if (G_IS_KDBUS_CONNECTION (connection->stream))
+              if (connection->kdbus_worker)
                 {
                   if (g_strcmp0 (signal_data->member, "NameAcquired") == 0)
-                    _g_kdbus_unsubscribe_name_acquired (connection);
+                    _g_kdbus_unsubscribe_name_acquired (connection->kdbus_worker);
                   else if (g_strcmp0 (signal_data->member, "NameLost") == 0)
-                    _g_kdbus_unsubscribe_name_lost (connection);
+                    _g_kdbus_unsubscribe_name_lost (connection->kdbus_worker);
                 }
             }