#include "gsimpleasyncresult.h"
#ifdef G_OS_UNIX
+#include "gkdbus.h"
#include "gunixconnection.h"
#include "gunixfdmessage.h"
#endif
static GWeakRef the_session_bus;
static GWeakRef the_system_bus;
+static GWeakRef the_user_bus;
+static GWeakRef the_machine_bus;
/* Extra pseudo-member of GDBusSendMessageFlags.
* Set by initable_init() to indicate that despite not being initialized yet,
* 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").
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);
}
/**
/* ---------------------------------------------------------------------------------------------------- */
/**
+ * g_dbus_request_name:
+ * @connection: a #GDBusConnection
+ * @name: well-known bus name (name to request)
+ * @flags: a set of flags from the GBusNameOwnerFlags enumeration
+ * @error: return location for error or %NULL
+ *
+ * Synchronously acquires name on the bus and returns status code.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: status code or %G_BUS_REQUEST_NAME_FLAGS_ERROR
+ * if @error is set.
+ *
+ * Since: 2.4x
+ */
+GBusRequestNameReplyFlags
+g_dbus_request_name (GDBusConnection *connection,
+ const gchar *name,
+ GBusNameOwnerFlags flags,
+ GError **error)
+{
+ GVariant *result;
+ guint32 request_name_reply;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), G_BUS_RELEASE_NAME_FLAGS_ERROR);
+ 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 (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",
+ g_variant_new ("(su)", name, flags), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+
+ if (result != NULL)
+ {
+ g_variant_get (result, "(u)", &request_name_reply);
+ g_variant_unref (result);
+ }
+ else
+ request_name_reply = G_BUS_REQUEST_NAME_FLAGS_ERROR;
+
+ return (GBusRequestNameReplyFlags) request_name_reply;
+}
+
+/**
+ * g_dbus_release_name:
+ * @connection: a #GDBusConnection
+ * @name: well-known bus name (name to release)
+ * @error: return location for error or %NULL
+ *
+ * Synchronously releases name on the bus and returns status code.
+ *
+ * The calling thread is blocked until a reply is received.
+ *
+ * Returns: status code or %G_BUS_RELEASE_NAME_FLAGS_ERROR
+ * if @error is set.
+ *
+ * Since: 2.4x
+ */
+GBusReleaseNameReplyFlags
+g_dbus_release_name (GDBusConnection *connection,
+ const gchar *name,
+ GError **error)
+{
+ GVariant *result;
+ guint32 release_name_reply;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), G_BUS_RELEASE_NAME_FLAGS_ERROR);
+ 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 (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",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+
+ if (result != NULL)
+ {
+ g_variant_get (result, "(u)", &release_name_reply);
+ g_variant_unref (result);
+ }
+ else
+ release_name_reply = G_BUS_RELEASE_NAME_FLAGS_ERROR;
+
+ return (GBusReleaseNameReplyFlags) release_name_reply;
+}
+
+/**
* g_dbus_get_bus_id:
* @connection: a #GDBusConnection
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
* @error: return location for error or %NULL
*
* Synchronously returns the unique ID of the bus.
*
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED.
- *
* The calling thread is blocked until a reply is received.
*
* Returns: the unique ID of the bus or %NULL if @error is set.
*/
gchar *
g_dbus_get_bus_id (GDBusConnection *connection,
- gint timeout_msec,
GError **error)
{
GVariant *result;
gchar *bus_id;
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
- g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
result = NULL;
bus_id = NULL;
- result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
- "org.freedesktop.DBus", "GetId",
- NULL, G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, error);
+ if (connection->kdbus_worker)
+ {
+ result = _g_kdbus_GetBusId (connection->kdbus_worker, error);
+ }
+ else
+ {
+ result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
+ "org.freedesktop.DBus", "GetId",
+ NULL, G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
+ }
+
if (result != NULL)
{
g_variant_get (result, "(s)", &bus_id);
_g_dbus_get_list_internal (GDBusConnection *connection,
const gchar *name,
GDBusListNameType list_name_type,
- gint timeout_msec,
GError **error)
{
gchar **strv;
if (list_name_type == LIST_QUEUED_OWNERS)
{
- result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
- "org.freedesktop.DBus", "ListQueuedOwners",
- g_variant_new ("(s)", name), G_VARIANT_TYPE ("(as)"),
- G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, 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",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(as)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
}
else
{
else
method_name = "ListActivatableNames";
- result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
- "org.freedesktop.DBus", method_name,
- NULL, G_VARIANT_TYPE ("(as)"),
- G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, 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,
+ NULL, G_VARIANT_TYPE ("(as)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
}
if (result != NULL)
/**
* g_dbus_get_list_names:
* @connection: a #GDBusConnection
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
* @error: return location for error or %NULL
*
* Synchronously returns a list of all currently-owned names on the bus.
*
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED.
- *
* The calling thread is blocked until a reply is received.
*
- * Returns: a list of all currently-owned names on the bus.
- * Free with g_strfreev().
+ * Returns: a list of all currently-owned names on the bus or %NULL if
+ * @error is set. Free with g_strfreev().
*
* Since: 2.4x
*/
gchar **
g_dbus_get_list_names (GDBusConnection *connection,
- gint timeout_msec,
GError **error)
{
gchar **strv;
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
- g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- strv = _g_dbus_get_list_internal (connection, NULL, LIST_NAMES, timeout_msec, error);
+ strv = _g_dbus_get_list_internal (connection, NULL, LIST_NAMES, error);
return strv;
}
/**
* g_dbus_get_list_activatable_names:
* @connection: a #GDBusConnection
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
* @error: return location for error or %NULL
*
* Synchronously returns a list of all names that can be activated on the bus.
*
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED.
- *
* The calling thread is blocked until a reply is received.
*
- * Returns: a list of all names that can be activated on the bus.
- * Free with g_strfreev().
+ * Returns: a list of all names that can be activated on the bus or %NULL if
+ * @error is set. Free with g_strfreev().
*
* Since: 2.4x
*/
gchar **
g_dbus_get_list_activatable_names (GDBusConnection *connection,
- gint timeout_msec,
GError **error)
{
gchar **strv;
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
- g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- strv = _g_dbus_get_list_internal (connection, NULL, LIST_ACTIVATABLE_NAMES, timeout_msec, error);
+ strv = _g_dbus_get_list_internal (connection, NULL, LIST_ACTIVATABLE_NAMES, error);
return strv;
}
* g_dbus_get_list_queued_names:
* @connection: a #GDBusConnection
* @name: a unique or well-known bus name
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
* @error: return location for error or %NULL
*
* Synchronously returns the unique bus names of connections currently queued
* for the @name.
*
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED. If @name contains a value not compatible with
- * the D-Bus syntax and naming conventions for bus names, the operation
- * returns %NULL.
+ * 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.
*
gchar **
g_dbus_get_list_queued_owners (GDBusConnection *connection,
const gchar *name,
- gint timeout_msec,
GError **error)
{
gchar **strv;
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 (timeout_msec >= 0 || timeout_msec == -1, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- strv = _g_dbus_get_list_internal (connection, name, LIST_QUEUED_OWNERS, timeout_msec, error);
+ strv = _g_dbus_get_list_internal (connection, name, LIST_QUEUED_OWNERS, error);
return strv;
}
* g_dbus_get_name_owner:
* @connection: a #GDBusConnection
* @name: well-known bus name to get the owner of
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
* @error: return location for error or %NULL
*
* Synchronously returns the unique connection name of the primary owner of
* the name given. If the requested name doesn't have an owner, an @error is
* returned.
*
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED. If @name contains a value not compatible with
- * the D-Bus syntax and naming conventions for bus names, the operation
- * returns %NULL.
+ * 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.
*
gchar *
g_dbus_get_name_owner (GDBusConnection *connection,
const gchar *name,
- gint timeout_msec,
GError **error)
{
GVariant *result;
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 (timeout_msec >= 0 || timeout_msec == -1, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
name_owner = NULL;
result = NULL;
- result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
- "org.freedesktop.DBus", "GetNameOwner",
- g_variant_new ("(s)", name), G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, 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",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(s)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
if (result != NULL)
{
g_variant_get (result, "(s)", &name_owner);
}
/**
- * g_dbus_name_has_owner:
- * @connection: a #GDBusConnection
- * @name: a unique or well-known bus name
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
- * @error: return location for error or %NULL
- *
- * Synchronously checks if the specified name exists (currently has an owner).
- *
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED. If @name contains a value not compatible with
- * the D-Bus syntax and naming conventions for bus names, the operation
- * returns FALSE.
- *
- * 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,
- gint timeout_msec,
- 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 (timeout_msec >= 0 || timeout_msec == -1, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- result = NULL;
-
- 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, timeout_msec, 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
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
* @error: return location for error or %NULL
*
* Synchronously returns the Unix process ID of the process connected to the
* bus. If unable to determine it, an @error is returned.
*
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED. If @name contains a value not compatible with
- * the D-Bus syntax and naming conventions for bus names, the operation
- * returns (guint32) -1.
+ * If @name contains a value not compatible with the D-Bus syntax and naming
+ * conventions for bus names, the operation returns (guint32) -1 and @error
+ * is set.
*
* The calling thread is blocked until a reply is received.
*
guint32
g_dbus_get_connection_pid (GDBusConnection *connection,
const gchar *name,
- gint timeout_msec,
GError **error)
{
GVariant *result;
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), -1);
g_return_val_if_fail (name == NULL || g_dbus_is_name (name), -1);
- g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, -1);
g_return_val_if_fail (error == NULL || *error == NULL, -1);
result = NULL;
pid = -1;
- result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
- "org.freedesktop.DBus", "GetConnectionUnixProcessID",
- g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
- G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, 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",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
if (result != NULL)
{
g_variant_get (result, "(u)", &pid);
* g_dbus_get_connection_uid:
* @connection: a #GDBusConnection
* @name: a unique or well-known bus name of the connection to query
- * @timeout_msec: the timeout in milliseconds, -1 to use the default timeout
* @error: return location for error or %NULL
*
* Synchronously returns the Unix user ID of the process connected to the
* bus. If unable to determine it, an @error is returned.
*
- * If @connection is closed then the operation will fail with
- * %G_IO_ERROR_CLOSED. If @name contains a value not compatible with
- * the D-Bus syntax and naming conventions for bus names, the operation
- * returns (guint32) -1.
+ * If @name contains a value not compatible with the D-Bus syntax and naming
+ * conventions for bus names, the operation returns (guint32) -1 and @error
+ * is set.
*
* The calling thread is blocked until a reply is received.
*
guint32
g_dbus_get_connection_uid (GDBusConnection *connection,
const gchar *name,
- gint timeout_msec,
GError **error)
{
GVariant *result;
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), -1);
g_return_val_if_fail (name == NULL || g_dbus_is_name (name), -1);
- g_return_val_if_fail (timeout_msec >= 0 || timeout_msec == -1, -1);
g_return_val_if_fail (error == NULL || *error == NULL, -1);
result = NULL;
uid = -1;
- result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/",
- "org.freedesktop.DBus", "GetConnectionUnixUser",
- g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
- G_DBUS_CALL_FLAGS_NONE, timeout_msec, NULL, 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",
+ g_variant_new ("(s)", name), G_VARIANT_TYPE ("(u)"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, error);
if (result != NULL)
{
g_variant_get (result, "(u)", &uid);
}
/* ---------------------------------------------------------------------------------------------------- */
-
+#include "gkdbus.h"
/* Can be called by any thread, with the connection lock held */
static gboolean
g_dbus_connection_send_message_unlocked (GDBusConnection *connection,
error))
goto out;
- blob = g_dbus_message_to_blob (message,
- &blob_size,
- connection->capabilities,
- error);
- if (blob == NULL)
- goto out;
+ if (!(flags & G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL))
+ g_dbus_message_set_serial (message, ++connection->last_serial);
- 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 */
+ serial_to_use = g_dbus_message_get_serial (message);
- switch (blob[0])
+ /*
+ * serializes message to a blob
+ */
+ if (connection->worker)
{
- case 'l':
- ((guint32 *) blob)[2] = GUINT32_TO_LE (serial_to_use);
- break;
- case 'B':
- ((guint32 *) blob)[2] = GUINT32_TO_BE (serial_to_use);
- break;
- default:
- g_assert_not_reached ();
- break;
+ blob = g_dbus_message_to_blob (message,
+ &blob_size,
+ connection->capabilities,
+ error);
+ if (blob == NULL)
+ goto out;
+
+ switch (blob[0])
+ {
+ case 'l':
+ ((guint32 *) blob)[2] = GUINT32_TO_LE (serial_to_use);
+ break;
+ case 'B':
+ ((guint32 *) blob)[2] = GUINT32_TO_BE (serial_to_use);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
}
+ g_dbus_message_lock (message);
+
#if 0
g_printerr ("Writing message of %" G_GSIZE_FORMAT " bytes (serial %d) on %p:\n",
blob_size, serial_to_use, 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);
+ ret = TRUE;
- g_dbus_message_lock (message);
- _g_dbus_worker_send_message (connection->worker,
- message,
- (gchar*) blob,
- blob_size);
- blob = NULL; /* since _g_dbus_worker_send_message() steals the blob */
+ if (connection->worker)
+ _g_dbus_worker_send_message (connection->worker,
+ message,
+ (gchar*) blob,
+ blob_size);
+ else
+ ret = g_kdbus_worker_send_message (connection->kdbus_worker, message, error);
- ret = TRUE;
+ blob = NULL; /* since _g_dbus_worker_send_message() steals the blob */
out:
g_free (blob);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
data = g_new0 (SendMessageSyncData, 1);
- data->context = g_main_context_new ();
+
+ if (connection->kdbus_worker)
+ data->context = g_main_context_ref_thread_default ();
+ else
+ data->context = g_main_context_new ();
+
data->loop = g_main_loop_new (data->context, FALSE);
g_main_context_push_thread_default (data->context);
/* 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;
/* 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;
/* 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;
GError **error)
{
GDBusConnection *connection = G_DBUS_CONNECTION (initable);
+ gboolean initially_frozen;
gboolean ret;
/* This method needs to be idempotent to work with the singleton
*/
if (connection->address != NULL)
{
+ GObject *ret;
+
g_assert (connection->stream == NULL);
if ((connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER) ||
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)
{
g_assert_not_reached ();
}
+ /* [KDBUS] Skip authentication process for kdbus transport */
+ if (connection->kdbus_worker)
+ {
+ goto authenticated;
+ }
+
/* Authenticate the connection */
if (connection->flags & G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER)
{
connection->authentication_observer = NULL;
}
+authenticated:
+
//g_output_stream_flush (G_SOCKET_CONNECTION (connection->stream)
//g_debug ("haz unix fd passing powers: %d", connection->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
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)
goto out;
}
- hello_result = g_dbus_connection_call_sync (connection,
- "org.freedesktop.DBus", /* name */
- "/org/freedesktop/DBus", /* path */
- "org.freedesktop.DBus", /* interface */
- "Hello",
- NULL, /* parameters */
- G_VARIANT_TYPE ("(s)"),
- CALL_FLAGS_INITIALIZING,
- -1,
- NULL, /* TODO: cancellable */
- &connection->initialization_error);
+ if (connection->kdbus_worker)
+ {
+ hello_result = _g_kdbus_Hello (connection->kdbus_worker, &connection->initialization_error);
+ }
+ else
+ {
+ hello_result = g_dbus_connection_call_sync (connection,
+ "org.freedesktop.DBus", /* name */
+ "/org/freedesktop/DBus", /* path */
+ "org.freedesktop.DBus", /* interface */
+ "Hello",
+ NULL, /* parameters */
+ G_VARIANT_TYPE ("(s)"),
+ CALL_FLAGS_INITIALIZING,
+ -1,
+ NULL, /* TODO: cancellable */
+ &connection->initialization_error);
+ }
+
if (hello_result == NULL)
goto out;
//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)
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 (connection->kdbus_worker)
+ {
+ if (g_strcmp0 (signal_data->member, "NameAcquired") == 0)
+ _g_kdbus_subscribe_name_acquired (connection->kdbus_worker, arg0);
+ else if (g_strcmp0 (signal_data->member, "NameLost") == 0)
+ _g_kdbus_subscribe_name_lost (connection->kdbus_worker, arg0);
+ }
+ }
}
signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
* 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 (connection->kdbus_worker)
+ {
+ if (g_strcmp0 (signal_data->member, "NameAcquired") == 0)
+ _g_kdbus_unsubscribe_name_acquired (connection->kdbus_worker);
+ else if (g_strcmp0 (signal_data->member, "NameLost") == 0)
+ _g_kdbus_unsubscribe_name_lost (connection->kdbus_worker);
+ }
}
signal_data_free (signal_data);
}
else
{
- g_variant_ref_sink (parameters);
+ g_variant_ref (parameters);
}
#if 0
ret = &the_system_bus;
break;
+ case G_BUS_TYPE_USER:
+ ret = &the_user_bus;
+ break;
+
+ case G_BUS_TYPE_MACHINE:
+ ret = &the_machine_bus;
+ break;
+
case G_BUS_TYPE_STARTER:
starter_bus = g_getenv ("DBUS_STARTER_BUS_TYPE");
if (g_strcmp0 (starter_bus, "session") == 0)