[glib/gdbus: 3/6] Ensure _new_for_connection() variants work with an unopened connection
- From: David Zeuthen <davidz src gnome org>
- To: svn-commits-list gnome org
- Subject: [glib/gdbus: 3/6] Ensure _new_for_connection() variants work with an unopened connection
- Date: Wed, 22 Apr 2009 11:45:14 -0400 (EDT)
commit 007945d4759880623d2f5d0363331622369c97b0
Author: David Zeuthen <davidz redhat com>
Date: Tue Apr 21 20:28:56 2009 -0400
Ensure _new_for_connection() variants work with an unopened connection
Also add g_bus_name_watcher_new_for_connection().
---
docs/reference/gdbus/gdbus-sections.txt | 3 +
gdbus/gbusnameowner.c | 411 ++++++++++++++++++++-----------
gdbus/gbusnamewatcher.c | 287 +++++++++++++---------
gdbus/gbusnamewatcher.h | 2 -
gdbus/gdbus.symbols | 3 +
gdbus/gdbusconnection.c | 45 ++++-
gdbus/gdbusconnection.h | 1 +
gdbus/tests/connection.c | 81 ++++---
8 files changed, 532 insertions(+), 301 deletions(-)
diff --git a/docs/reference/gdbus/gdbus-sections.txt b/docs/reference/gdbus/gdbus-sections.txt
index 0550195..7149c28 100644
--- a/docs/reference/gdbus/gdbus-sections.txt
+++ b/docs/reference/gdbus/gdbus-sections.txt
@@ -29,6 +29,8 @@ GBusNameWatcher
GBusNameWatcherClass
g_bus_name_watcher_new
g_bus_name_watcher_new_finish
+g_bus_name_watcher_new_for_connection
+g_bus_name_watcher_new_for_connection_finish
g_bus_name_watcher_get_name
g_bus_name_watcher_get_name_owner
g_bus_name_watcher_get_flags
@@ -57,6 +59,7 @@ g_dbus_connection_get_exit_on_close
g_dbus_connection_set_exit_on_close
g_dbus_connection_get_unique_name
g_dbus_connection_get_is_open
+g_dbus_connection_get_is_opening
g_dbus_connection_get_bus_type
g_dbus_connection_get_dbus_1_connection
<SUBSECTION Standard>
diff --git a/gdbus/gbusnameowner.c b/gdbus/gbusnameowner.c
index 9f6185a..4bf003b 100644
--- a/gdbus/gbusnameowner.c
+++ b/gdbus/gbusnameowner.c
@@ -52,7 +52,9 @@ struct _GBusNameOwnerPrivate
gboolean owns_name;
- gboolean in_construction_phase;
+ /* these variables are used to store async callbacks for users calling _new() */
+ gboolean in_init_phase;
+ GPtrArray *init_phase_pending_simple_async_results;
};
enum
@@ -71,6 +73,11 @@ enum
LAST_SIGNAL,
};
+G_LOCK_DEFINE_STATIC (owner_lock);
+
+static GBusNameOwner *singletons_get_owner (GDBusConnection *connection, const gchar *name);
+static void singletons_add_owner (GBusNameOwner *owner);
+static void singletons_remove_owner (GBusNameOwner *owner);
static DBusHandlerResult
filter_function (DBusConnection *dbus_1_connection,
@@ -113,6 +120,19 @@ static guint get_request_name_flags (GBusNameOwnerFlags flags);
G_DEFINE_TYPE (GBusNameOwner, g_bus_name_owner, G_TYPE_OBJECT);
static void
+g_bus_name_owner_dispose (GObject *object)
+{
+ GBusNameOwner *owner = G_BUS_NAME_OWNER (object);
+
+ G_LOCK (owner_lock);
+ singletons_remove_owner (owner);
+ G_UNLOCK (owner_lock);
+
+ if (G_OBJECT_CLASS (g_bus_name_owner_parent_class)->dispose != NULL)
+ G_OBJECT_CLASS (g_bus_name_owner_parent_class)->dispose (object);
+}
+
+static void
g_bus_name_owner_finalize (GObject *object)
{
GBusNameOwner *owner = G_BUS_NAME_OWNER (object);
@@ -361,7 +381,7 @@ on_connection_opened (GDBusConnection *connection,
NULL))
_g_dbus_oom ();
- if (owner->priv->in_construction_phase)
+ if (owner->priv->in_init_phase)
return;
/* ok, the bus suddenly came up.. so try to claim the name ASAP */
@@ -418,6 +438,7 @@ g_bus_name_owner_class_init (GBusNameOwnerClass *klass)
g_type_class_add_private (klass, sizeof (GBusNameOwnerPrivate));
gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->dispose = g_bus_name_owner_dispose;
gobject_class->finalize = g_bus_name_owner_finalize;
gobject_class->constructed = g_bus_name_owner_constructed;
gobject_class->get_property = g_bus_name_owner_get_property;
@@ -532,7 +553,8 @@ static void
g_bus_name_owner_init (GBusNameOwner *owner)
{
owner->priv = G_TYPE_INSTANCE_GET_PRIVATE (owner, G_TYPE_BUS_NAME_OWNER, GBusNameOwnerPrivate);
- owner->priv->in_construction_phase = TRUE;
+ owner->priv->in_init_phase = TRUE;
+ owner->priv->init_phase_pending_simple_async_results = g_ptr_array_new ();
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -865,112 +887,276 @@ bus_request_name_finish (GDBusConnection *bus,
}
/* ---------------------------------------------------------------------------------------------------- */
+/* routines used for singleton handling */
+
+/* maps from connection to GHashTable (that maps from names to GBusNameOwner) */
+static GHashTable *map_connection_to_map_of_owned_names_to_owner = NULL;
-typedef struct
+/* the following singletons_* functions must be called with owner_lock held */
+
+/* called from _new() before creating a GBusNameOwner - result is not reffed */
+static GBusNameOwner *
+singletons_get_owner (GDBusConnection *connection, const gchar *name)
{
- GAsyncReadyCallback callback;
- gpointer user_data;
- GBusNameOwner *owner;
- gboolean is_for_connection;
-} ConstructData;
+ GBusNameOwner *ret;
+ GHashTable *map_of_owned_names_to_owner;
+
+ g_return_val_if_fail (connection != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ ret = NULL;
+
+ if (map_connection_to_map_of_owned_names_to_owner == NULL)
+ goto out;
+
+ map_of_owned_names_to_owner = g_hash_table_lookup (map_connection_to_map_of_owned_names_to_owner,
+ connection);
+ if (map_of_owned_names_to_owner == NULL)
+ goto out;
+
+ ret = g_hash_table_lookup (map_of_owned_names_to_owner,
+ name);
+
+ out:
+ return ret;
+}
+/* called from _new() after creating the GBusNameOwner */
static void
-construct_data_free (ConstructData *data)
+singletons_add_owner (GBusNameOwner *owner)
{
- g_free (data);
+ GHashTable *map_of_owned_names_to_owner;
+
+ g_return_if_fail (owner != NULL);
+
+ if (map_connection_to_map_of_owned_names_to_owner == NULL)
+ map_connection_to_map_of_owned_names_to_owner = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ map_of_owned_names_to_owner = g_hash_table_lookup (map_connection_to_map_of_owned_names_to_owner,
+ owner->priv->connection);
+ if (map_of_owned_names_to_owner == NULL)
+ {
+ map_of_owned_names_to_owner = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (map_connection_to_map_of_owned_names_to_owner,
+ owner->priv->connection,
+ map_of_owned_names_to_owner);
+ }
+
+ g_hash_table_insert (map_of_owned_names_to_owner,
+ owner->priv->name,
+ owner);
+}
+
+/* called from dispose() - ie. can be called multiple times so don't assert anything */
+static void
+singletons_remove_owner (GBusNameOwner *owner)
+{
+ GHashTable *map_of_owned_names_to_owner;
+
+ if (map_connection_to_map_of_owned_names_to_owner == NULL)
+ goto out;
+
+ map_of_owned_names_to_owner = g_hash_table_lookup (map_connection_to_map_of_owned_names_to_owner,
+ owner->priv->connection);
+ if (map_of_owned_names_to_owner == NULL)
+ goto out;
+
+ if (!g_hash_table_remove (map_of_owned_names_to_owner,
+ owner->priv->name))
+ goto out;
+
+ /* clean up as needed */
+ if (g_hash_table_size (map_of_owned_names_to_owner) == 0)
+ {
+ g_hash_table_remove (map_connection_to_map_of_owned_names_to_owner, owner->priv->connection);
+ g_hash_table_destroy (map_of_owned_names_to_owner);
+
+ if (g_hash_table_size (map_connection_to_map_of_owned_names_to_owner) == 0)
+ {
+ g_hash_table_destroy (map_connection_to_map_of_owned_names_to_owner);
+ map_connection_to_map_of_owned_names_to_owner = NULL;
+ }
+ }
+
+ out:
+ ;
}
+/* ---------------------------------------------------------------------------------------------------- */
static void
request_name_cb (GDBusConnection *connection,
GAsyncResult *result,
gpointer user_data)
{
- ConstructData *data = user_data;
+ GBusNameOwner *owner = G_BUS_NAME_OWNER (user_data);
GSimpleAsyncResult *simple;
GError *error;
guint reply;
-
- simple = g_simple_async_result_new (G_OBJECT (data->owner),
- data->callback,
- data->user_data,
- data->is_for_connection ? g_bus_name_owner_new_for_connection_finish : g_bus_name_owner_new_finish);
+ guint n;
error = NULL;
reply = bus_request_name_finish (connection,
result,
&error);
+ G_LOCK (owner_lock);
if (error != NULL)
{
- g_simple_async_result_set_from_error (simple,
- error);
+ /* report error back */
+ for (n = 0; n < owner->priv->init_phase_pending_simple_async_results->len; n++)
+ {
+ simple = G_SIMPLE_ASYNC_RESULT (owner->priv->init_phase_pending_simple_async_results->pdata[n]);
+ g_simple_async_result_set_from_error (simple, error);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ }
g_error_free (error);
}
else
{
- if (reply != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
- {
- g_simple_async_result_set_error (simple,
- G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- _("Error acquiring name, RequestName() returned %d"),
- reply);
- }
- else
+ if (reply == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+ owner->priv->owns_name = TRUE;
+
+ /* complete operations without error */
+ for (n = 0; n < owner->priv->init_phase_pending_simple_async_results->len; n++)
{
- data->owner->priv->owns_name = TRUE;
- g_signal_emit (data->owner, signals[NAME_ACQUIRED_SIGNAL], 0);
+ simple = G_SIMPLE_ASYNC_RESULT (owner->priv->init_phase_pending_simple_async_results->pdata[n]);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
}
}
- data->owner->priv->in_construction_phase = FALSE;
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- construct_data_free (data);
+ owner->priv->in_init_phase = FALSE;
+ g_ptr_array_free (owner->priv->init_phase_pending_simple_async_results, TRUE);
+ owner->priv->init_phase_pending_simple_async_results = NULL;
+ G_UNLOCK (owner_lock);
}
static void
-get_connection_cb (GDBusConnection *connection,
- GAsyncResult *result,
- gpointer user_data)
+on_notify_is_opening (GDBusConnection *connection,
+ GParamSpec *spec,
+ gpointer user_data)
{
- ConstructData *data = user_data;
- GError *error;
+ GBusNameOwner *owner = G_BUS_NAME_OWNER (user_data);
- error = NULL;
- if (!g_dbus_connection_bus_get_finish (connection,
- result,
- &error))
- {
- GSimpleAsyncResult *simple;
-
- /* connection is not open.. report back */
- simple = g_simple_async_result_new (G_OBJECT (data->owner),
- data->callback,
- data->user_data,
- g_bus_name_owner_new_finish);
- g_simple_async_result_set_from_error (simple,
- error);
- g_error_free (error);
+ /* connection is not opening anymore.. try to own the name */
+ bus_request_name (owner->priv->connection,
+ owner->priv->name,
+ get_request_name_flags (owner->priv->flags),
+ (GAsyncReadyCallback) request_name_cb,
+ owner);
- data->owner->priv->in_construction_phase = FALSE;
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- construct_data_free (data);
+ g_signal_handlers_disconnect_by_func (connection, on_notify_is_opening, owner);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GBusNameOwner *
+g_bus_name_owner_new_internal (GMessageBusType bus_type,
+ GDBusConnection *given_connection,
+ const gchar *name,
+ GBusNameOwnerFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GBusNameOwner *owner;
+ GDBusConnection *connection;
+ GSimpleAsyncResult *simple;
+ gpointer source_tag;
+
+ /* This is all a tad complicated since we support singletons... the problem here
+ * in a nutshell is that there's a window, an initialization phase, where we
+ *
+ * - wait until the connection is no longer in an opening state
+ * - and for the reply for the HasNameOwner() method invocation
+ *
+ * Now, suppose the user creates two owner objects with the same bus and name
+ * and no bus is up. The second one will just be a reference to the first one
+ * because we support singletons. So basically while we are initializing, just
+ * add the callback for the second owner to a list on the first one. Then
+ * when initialization is done, fire all callbacks.
+ */
+
+ if (given_connection != NULL)
+ {
+ source_tag = g_bus_name_owner_new_for_connection_finish;
+ connection = g_object_ref (given_connection);
}
else
{
- /* connection is open.. try to claim the name */
+ source_tag = g_bus_name_owner_new_finish;
+ connection = g_dbus_connection_bus_get (bus_type,
+ NULL,
+ NULL,
+ NULL);
+ }
+
+ G_LOCK (owner_lock);
+ /* check if a suitable owner already exists */
+ owner = singletons_get_owner (connection, name);
+ if (owner != NULL)
+ {
+ simple = g_simple_async_result_new (G_OBJECT (owner),
+ callback,
+ user_data,
+ source_tag);
+
+ if (owner->priv->in_init_phase)
+ {
+ /* if still initializing, defer callback until we know what stuff looks like */
+ g_ptr_array_add (owner->priv->init_phase_pending_simple_async_results, simple);
+ }
+ else
+ {
+ /* otherwise, return the result right away (e.g. in idle) */
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ }
+ g_object_ref (owner);
+ goto out;
+ }
+
+ owner = G_BUS_NAME_OWNER (g_object_new (G_TYPE_BUS_NAME_OWNER,
+ "name", name,
+ "flags", flags,
+ "connection", connection,
+ NULL));
+
+ simple = g_simple_async_result_new (G_OBJECT (owner),
+ callback,
+ user_data,
+ source_tag);
- bus_request_name (data->owner->priv->connection,
- data->owner->priv->name,
- get_request_name_flags (data->owner->priv->flags),
+ g_ptr_array_add (owner->priv->init_phase_pending_simple_async_results, simple);
+
+ singletons_add_owner (owner);
+
+ if (g_dbus_connection_get_is_opening (connection))
+ {
+ /* connection is opening.. so wait until it is done opening */
+ g_signal_connect (connection,
+ "notify::is-opening",
+ G_CALLBACK (on_notify_is_opening),
+ owner);
+ }
+ else
+ {
+ /* connection is not opening.. try to claim the name */
+ bus_request_name (owner->priv->connection,
+ owner->priv->name,
+ get_request_name_flags (owner->priv->flags),
(GAsyncReadyCallback) request_name_cb,
- data);
+ owner);
}
-}
-/* ---------------------------------------------------------------------------------------------------- */
+ out:
+ G_UNLOCK (owner_lock);
+
+ g_object_unref (connection);
+
+ return owner;
+}
/**
* g_bus_name_owner_new:
@@ -986,6 +1172,9 @@ get_connection_cb (GDBusConnection *connection,
* finished, @callback will be invoked (on the main thread) and you
* can use g_bus_name_owner_new_finish() to get the result.
*
+ * Note that the returned object may be shared with other callers if
+ * @bus_type and @name matches.
+ *
* This class is the preferred way to implement D-Bus
* services. The canonical example follows.
* <example><title>Using g_bus_name_owner_new()</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gdbus/example-gbusnameowner.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
@@ -1000,30 +1189,13 @@ g_bus_name_owner_new (GMessageBusType bus_type,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GBusNameOwner *owner;
- GDBusConnection *connection;
- ConstructData *data;
-
- data = g_new0 (ConstructData, 1);
- data->callback = callback;
- data->user_data = user_data;
-
- connection = g_dbus_connection_bus_get (bus_type,
- cancellable,
- (GAsyncReadyCallback) get_connection_cb,
- data);
-
- owner = G_BUS_NAME_OWNER (g_object_new (G_TYPE_BUS_NAME_OWNER,
- "name", name,
- "connection", connection,
- "flags", flags,
- NULL));
-
- data->owner = owner;
-
- g_object_unref (connection);
-
- return owner;
+ return g_bus_name_owner_new_internal (bus_type,
+ NULL,
+ name,
+ flags,
+ cancellable,
+ callback,
+ user_data);
}
/**
@@ -1034,7 +1206,8 @@ g_bus_name_owner_new (GMessageBusType bus_type,
*
* Finishes attempting to acquire a name.
*
- * Returns: %TRUE if the name was acquired, otherwise %FALSE with @error set.
+ * Returns: %TRUE if the attempt to acquired the name succeed (the name may not have been
+ * acquired, check with g_bus_name_owner_get_owns_name()), otherwise %FALSE with @error set.
**/
gboolean
g_bus_name_owner_new_finish (GBusNameOwner *owner,
@@ -1042,16 +1215,12 @@ g_bus_name_owner_new_finish (GBusNameOwner *owner,
GError **error)
{
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-
g_return_val_if_fail (G_IS_BUS_NAME_OWNER (owner), FALSE);
-
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_bus_name_owner_new_finish);
-
return !g_simple_async_result_propagate_error (simple, error);
}
/* ---------------------------------------------------------------------------------------------------- */
-
/**
* g_bus_name_owner_new_for_connection:
* @connection: A #GDBusConnection.
@@ -1074,52 +1243,13 @@ g_bus_name_owner_new_for_connection (GDBusConnection *connection,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GBusNameOwner *owner;
-
- owner = G_BUS_NAME_OWNER (g_object_new (G_TYPE_BUS_NAME_OWNER,
- "name", name,
- "connection", connection,
- "flags", flags,
- NULL));
-
- if (g_dbus_connection_get_is_open (connection))
- {
- ConstructData *data;
- data = g_new0 (ConstructData, 1);
- data->callback = callback;
- data->user_data = user_data;
- data->is_for_connection = TRUE;
- data->owner = owner;
-
- /* connection is open.. try to claim the name */
- bus_request_name (data->owner->priv->connection,
- data->owner->priv->name,
- get_request_name_flags (data->owner->priv->flags),
- (GAsyncReadyCallback) request_name_cb,
- data);
- }
- else
- {
- GSimpleAsyncResult *simple;
-
- /* connection is not open.. report back in idle
- *
- * TODO: maybe handle g_dbus_connection_is_connecting() or something...
- */
- simple = g_simple_async_result_new (G_OBJECT (owner),
- callback,
- user_data,
- g_bus_name_owner_new_for_connection_finish);
- g_simple_async_result_set_error (simple,
- G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- _("Connection is not open"));
-
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
-
- return owner;
+ return g_bus_name_owner_new_internal (G_MESSAGE_BUS_TYPE_NONE,
+ connection,
+ name,
+ flags,
+ cancellable,
+ callback,
+ user_data);
}
/**
@@ -1146,7 +1276,6 @@ g_bus_name_owner_new_for_connection_finish (GBusNameOwner *owner,
return !g_simple_async_result_propagate_error (simple, error);
}
-
/* ---------------------------------------------------------------------------------------------------- */
/**
diff --git a/gdbus/gbusnamewatcher.c b/gdbus/gbusnamewatcher.c
index 2e9f778..d540040 100644
--- a/gdbus/gbusnamewatcher.c
+++ b/gdbus/gbusnamewatcher.c
@@ -497,6 +497,7 @@ g_bus_name_watcher_init (GBusNameWatcher *watcher)
{
watcher->priv = G_TYPE_INSTANCE_GET_PRIVATE (watcher, G_TYPE_BUS_NAME_WATCHER, GBusNameWatcherPrivate);
watcher->priv->in_init_phase = TRUE;
+ watcher->priv->init_phase_pending_simple_async_results = g_ptr_array_new ();
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -912,23 +913,12 @@ singletons_remove_watcher (GBusNameWatcher *watcher)
/* ---------------------------------------------------------------------------------------------------- */
-typedef struct
-{
- GBusNameWatcher *watcher;
-} ConstructData;
-
-static void
-construct_data_free (ConstructData *data)
-{
- g_free (data);
-}
-
static void
get_name_owner_cb (GDBusConnection *connection,
GAsyncResult *result,
gpointer user_data)
{
- ConstructData *data = user_data;
+ GBusNameWatcher *watcher = G_BUS_NAME_WATCHER (user_data);
GSimpleAsyncResult *simple;
GError *error;
gchar *name_owner;
@@ -941,13 +931,12 @@ get_name_owner_cb (GDBusConnection *connection,
G_LOCK (watcher_lock);
- /* NAME_HAS_NO_OWNER error => don't report this as an error, it just means there is no name owner */
- if (error != NULL && (error->domain != G_DBUS_ERROR && error->code != G_DBUS_ERROR_NAME_HAS_NO_OWNER))
+ if (error != NULL)
{
/* report error back */
- for (n = 0; n < data->watcher->priv->init_phase_pending_simple_async_results->len; n++)
+ for (n = 0; n < watcher->priv->init_phase_pending_simple_async_results->len; n++)
{
- simple = G_SIMPLE_ASYNC_RESULT (data->watcher->priv->init_phase_pending_simple_async_results->pdata[n]);
+ simple = G_SIMPLE_ASYNC_RESULT (watcher->priv->init_phase_pending_simple_async_results->pdata[n]);
g_simple_async_result_set_from_error (simple, error);
g_simple_async_result_complete_in_idle (simple);
g_object_unref (simple);
@@ -956,118 +945,54 @@ get_name_owner_cb (GDBusConnection *connection,
}
else
{
- g_free (data->watcher->priv->name_owner);
- if (error != NULL)
- {
- g_error_free (error);
- data->watcher->priv->name_owner = NULL;
- }
- else
- {
- data->watcher->priv->name_owner = name_owner; /* steals the returned string */
- }
+ watcher->priv->name_owner = name_owner; /* steals the returned string */
/* complete operations without error */
- for (n = 0; n < data->watcher->priv->init_phase_pending_simple_async_results->len; n++)
+ for (n = 0; n < watcher->priv->init_phase_pending_simple_async_results->len; n++)
{
- simple = G_SIMPLE_ASYNC_RESULT (data->watcher->priv->init_phase_pending_simple_async_results->pdata[n]);
+ simple = G_SIMPLE_ASYNC_RESULT (watcher->priv->init_phase_pending_simple_async_results->pdata[n]);
g_simple_async_result_complete_in_idle (simple);
g_object_unref (simple);
}
}
- data->watcher->priv->in_init_phase = FALSE;
- g_ptr_array_free (data->watcher->priv->init_phase_pending_simple_async_results, TRUE);
+ watcher->priv->in_init_phase = FALSE;
+ g_ptr_array_free (watcher->priv->init_phase_pending_simple_async_results, TRUE);
+ watcher->priv->init_phase_pending_simple_async_results = NULL;
G_UNLOCK (watcher_lock);
+}
- construct_data_free (data);
-}
+/* ---------------------------------------------------------------------------------------------------- */
static void
-get_connection_cb (GDBusConnection *connection,
- GAsyncResult *result,
- gpointer user_data)
+on_notify_is_opening (GDBusConnection *connection,
+ GParamSpec *spec,
+ gpointer user_data)
{
- ConstructData *data = user_data;
- GError *error;
-
- if (data->watcher == NULL)
- goto out;
-
- error = NULL;
- if (!g_dbus_connection_bus_get_finish (connection,
- result,
- &error))
- {
- GSimpleAsyncResult *simple;
- guint n;
-
- G_LOCK (watcher_lock);
- /* connection is not open.. report back */
- for (n = 0; n < data->watcher->priv->init_phase_pending_simple_async_results->len; n++)
- {
- simple = G_SIMPLE_ASYNC_RESULT (data->watcher->priv->init_phase_pending_simple_async_results->pdata[n]);
- g_simple_async_result_set_from_error (simple, error);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- }
- data->watcher->priv->in_init_phase = FALSE;
- g_ptr_array_free (data->watcher->priv->init_phase_pending_simple_async_results, TRUE);
- G_UNLOCK (watcher_lock);
-
- g_error_free (error);
+ GBusNameWatcher *watcher = G_BUS_NAME_WATCHER (user_data);
- construct_data_free (data);
- }
- else
- {
- /* connection is open.. check if the name exists */
- bus_get_name_owner (data->watcher->priv->connection,
- data->watcher->priv->name,
- (GAsyncReadyCallback) get_name_owner_cb,
- data);
- }
+ /* connection is open.. check if the name exists */
+ bus_get_name_owner (watcher->priv->connection,
+ watcher->priv->name,
+ (GAsyncReadyCallback) get_name_owner_cb,
+ watcher);
- out:
- ;
+ g_signal_handlers_disconnect_by_func (connection, on_notify_is_opening, watcher);
}
-/* ---------------------------------------------------------------------------------------------------- */
-
-/**
- * g_bus_name_watcher_new:
- * @bus_type: A #GMessageBusType specifying what message bus to connect to.
- * @name: A bus name (well-known or unique).
- * @cancellable: %NULL or a #GCancellable.
- * @callback: The callback function to invoke when finished acquiring the name.
- * @user_data: User data to pass to @callback.
- *
- * Creates a new #GBusNameWatcher and then check if someone owns @name
- * on the bus specified by @bus_type. When the check is finished,
- * @callback will be invoked (on the main thread) and you can use
- * g_bus_name_watcher_new_finish() to get the result.
- *
- * Note that the returned object may be shared with other callers if
- * @bus_type and @name matches.
- *
- * This class is the preferred way to implement D-Bus clients.
- * The canonical example follows.
- * <example><title>Using g_bus_name_watcher_new()</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gdbus/example-gbusnamewatcher.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
- *
- * Returns: A #GBusNameWatcher object. Free with g_object_unref().
- **/
-GBusNameWatcher *
-g_bus_name_watcher_new (GMessageBusType bus_type,
- const gchar *name,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static GBusNameWatcher *
+g_bus_name_watcher_new_internal (GMessageBusType bus_type,
+ GDBusConnection *given_connection,
+ const gchar *name,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GBusNameWatcher *watcher;
GDBusConnection *connection;
- ConstructData *data;
GSimpleAsyncResult *simple;
+ gpointer source_tag;
/* This is all a tad complicated since we support singletons... the problem here
* in a nutshell is that there's a window, an initialization phase, where we wait
@@ -1083,12 +1008,19 @@ g_bus_name_watcher_new (GMessageBusType bus_type,
* when initialization is done, fire all callbacks.
*/
- data = g_new0 (ConstructData, 1);
-
- connection = g_dbus_connection_bus_get (bus_type,
- cancellable,
- (GAsyncReadyCallback) get_connection_cb,
- data);
+ if (given_connection != NULL)
+ {
+ source_tag = g_bus_name_watcher_new_for_connection_finish;
+ connection = g_object_ref (given_connection);
+ }
+ else
+ {
+ source_tag = g_bus_name_watcher_new_finish;
+ connection = g_dbus_connection_bus_get (bus_type,
+ NULL,
+ NULL,
+ NULL);
+ }
G_LOCK (watcher_lock);
/* check if a suitable watcher already exists */
@@ -1098,7 +1030,7 @@ g_bus_name_watcher_new (GMessageBusType bus_type,
simple = g_simple_async_result_new (G_OBJECT (watcher),
callback,
user_data,
- g_bus_name_watcher_new_finish);
+ source_tag);
if (watcher->priv->in_init_phase)
{
@@ -1120,19 +1052,32 @@ g_bus_name_watcher_new (GMessageBusType bus_type,
"connection", connection,
NULL));
- data->watcher = watcher;
- watcher->priv->in_init_phase = TRUE;
- watcher->priv->init_phase_pending_simple_async_results = g_ptr_array_new ();
-
simple = g_simple_async_result_new (G_OBJECT (watcher),
callback,
user_data,
- g_bus_name_watcher_new_finish);
+ source_tag);
g_ptr_array_add (watcher->priv->init_phase_pending_simple_async_results, simple);
singletons_add_watcher (watcher);
+ if (g_dbus_connection_get_is_opening (connection))
+ {
+ /* connection is opening.. so wait until it is done opening */
+ g_signal_connect (connection,
+ "notify::is-opening",
+ G_CALLBACK (on_notify_is_opening),
+ watcher);
+ }
+ else
+ {
+ /* connection is open.. check if the name exists */
+ bus_get_name_owner (watcher->priv->connection,
+ watcher->priv->name,
+ (GAsyncReadyCallback) get_name_owner_cb,
+ watcher);
+ }
+
out:
G_UNLOCK (watcher_lock);
@@ -1141,17 +1086,57 @@ g_bus_name_watcher_new (GMessageBusType bus_type,
return watcher;
}
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * g_bus_name_watcher_new:
+ * @bus_type: A #GMessageBusType specifying what message bus to connect to.
+ * @name: A bus name (well-known or unique).
+ * @cancellable: %NULL or a #GCancellable.
+ * @callback: The callback function to invoke when finished acquiring the name.
+ * @user_data: User data to pass to @callback.
+ *
+ * Creates a new #GBusNameWatcher and then check if someone owns @name
+ * on the bus specified by @bus_type. When the check is finished,
+ * @callback will be invoked (on the main thread) and you can use
+ * g_bus_name_watcher_new_finish() to get the result.
+ *
+ * Note that the returned object may be shared with other callers if
+ * @bus_type and @name matches.
+ *
+ * This class is the preferred way to implement D-Bus clients.
+ * The canonical example follows.
+ * <example><title>Using g_bus_name_watcher_new()</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gdbus/example-gbusnamewatcher.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ *
+ * Returns: A #GBusNameWatcher object. Free with g_object_unref().
+ **/
+GBusNameWatcher *
+g_bus_name_watcher_new (GMessageBusType bus_type,
+ const gchar *name,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ return g_bus_name_watcher_new_internal (bus_type,
+ NULL,
+ name,
+ cancellable,
+ callback,
+ user_data);
+}
+
/**
* g_bus_name_watcher_new_finish:
* @watcher: A #GBusNameWatcher.
- * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback function passed to g_bus_name_watcher_get().
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback function passed to g_bus_name_watcher_new().
* @error: Return location for error or %NULL.
*
* Finishes attempting to determine the owner of the name being
* watched.
*
- * Returns: %TRUE if the name being watched has an owner or %FALSE if
- * there is no name owner or @error is set.
+ * Returns: %TRUE if it was possible to check if name has an owner (the name may not have an
+ * owner, check with g_dbus_name_watcher_get_name_owner()), otherwise %FALSE with @error
+ * set.
**/
gboolean
g_bus_name_watcher_new_finish (GBusNameWatcher *watcher,
@@ -1173,6 +1158,66 @@ g_bus_name_watcher_new_finish (GBusNameWatcher *watcher,
/* ---------------------------------------------------------------------------------------------------- */
/**
+ * g_bus_name_watcher_new_for_connection:
+ * @connection: A #GDBusConnection.
+ * @name: A bus name (well-known or unique).
+ * @cancellable: %NULL or a #GCancellable.
+ * @callback: The callback function to invoke when finished acquiring the name.
+ * @user_data: User data to pass to @callback.
+ *
+ * Like g_bus_name_watcher_new() but allows you to supply a
+ * #GDBusConnection.
+ *
+ * Returns: A #GBusNameWatcher object. Free with g_object_unref().
+ **/
+GBusNameWatcher *
+g_bus_name_watcher_new_for_connection (GDBusConnection *connection,
+ const gchar *name,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ return g_bus_name_watcher_new_internal (G_MESSAGE_BUS_TYPE_NONE,
+ connection,
+ name,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * g_bus_name_watcher_new_for_connection_finish:
+ * @watcher: A #GBusNameWatcher.
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback function passed to g_bus_name_watcher_new_for_connection().
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes attempting to determine the owner of the name being
+ * watched.
+ *
+ * Returns: %TRUE if it was possible to check if name has an owner (the name may not have an
+ * owner, check with g_dbus_name_watcher_get_name_owner()), otherwise %FALSE with @error
+ * set.
+ **/
+gboolean
+g_bus_name_watcher_new_for_connection_finish (GBusNameWatcher *watcher,
+ GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+ g_return_val_if_fail (G_IS_BUS_NAME_WATCHER (watcher), FALSE);
+
+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_bus_name_watcher_new_finish);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ return watcher->priv->name_owner != NULL;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
* g_bus_name_watcher_get_name:
* @watcher: A #GBusNameWatcher.
*
diff --git a/gdbus/gbusnamewatcher.h b/gdbus/gbusnamewatcher.h
index 544f988..90f58b9 100644
--- a/gdbus/gbusnamewatcher.h
+++ b/gdbus/gbusnamewatcher.h
@@ -94,7 +94,6 @@ GBusNameWatcher *g_bus_name_watcher_new (GMessageBusTyp
gboolean g_bus_name_watcher_new_finish (GBusNameWatcher *watcher,
GAsyncResult *res,
GError **error);
-#if 0
GBusNameWatcher *g_bus_name_watcher_new_for_connection (GDBusConnection *connection,
const gchar *name,
GCancellable *cancellable,
@@ -103,7 +102,6 @@ GBusNameWatcher *g_bus_name_watcher_new_for_connection (GDBusConnectio
gboolean g_bus_name_watcher_new_for_connection_finish (GBusNameWatcher *watcher,
GAsyncResult *res,
GError **error);
-#endif
const gchar *g_bus_name_watcher_get_name (GBusNameWatcher *watcher);
const gchar *g_bus_name_watcher_get_name_owner (GBusNameWatcher *watcher);
GDBusConnection *g_bus_name_watcher_get_connection (GBusNameWatcher *watcher);
diff --git a/gdbus/gdbus.symbols b/gdbus/gdbus.symbols
index 018250c..c68b694 100644
--- a/gdbus/gdbus.symbols
+++ b/gdbus/gdbus.symbols
@@ -22,6 +22,7 @@ g_dbus_connection_bus_get_private
g_dbus_connection_bus_get_private_finish
g_dbus_connection_get_unique_name
g_dbus_connection_get_is_open
+g_dbus_connection_get_is_opening
g_dbus_connection_get_bus_type
g_dbus_connection_get_dbus_1_connection
g_dbus_connection_get_exit_on_close
@@ -47,6 +48,8 @@ g_bus_name_owner_get_type
#if IN_FILE(__G_BUS_NAME_WATCHER_C__)
g_bus_name_watcher_new
g_bus_name_watcher_new_finish
+g_bus_name_watcher_new_for_connection
+g_bus_name_watcher_new_for_connection_finish
g_bus_name_watcher_get_connection
g_bus_name_watcher_get_name
g_bus_name_watcher_get_name_owner
diff --git a/gdbus/gdbusconnection.c b/gdbus/gdbusconnection.c
index 5c4b5a3..533953a 100644
--- a/gdbus/gdbusconnection.c
+++ b/gdbus/gdbusconnection.c
@@ -79,6 +79,7 @@ enum
PROP_BUS_TYPE,
PROP_UNIQUE_NAME,
PROP_IS_OPEN,
+ PROP_IS_OPENING,
PROP_EXIT_ON_CLOSE,
PROP_DBUS_1_CONNECTION,
};
@@ -159,6 +160,10 @@ g_dbus_connection_get_property (GObject *object,
g_value_set_boolean (value, g_dbus_connection_get_is_open (connection));
break;
+ case PROP_IS_OPENING:
+ g_value_set_boolean (value, g_dbus_connection_get_is_opening (connection));
+ break;
+
case PROP_EXIT_ON_CLOSE:
g_value_set_boolean (value, g_dbus_connection_get_exit_on_close (connection));
break;
@@ -263,7 +268,7 @@ g_dbus_connection_class_init (GDBusConnectionClass *klass)
* connection is closed or not a message bus connection.
*/
g_object_class_install_property (gobject_class,
- PROP_IS_OPEN,
+ PROP_UNIQUE_NAME,
g_param_spec_string ("unique-name",
_("unique-name"),
_("Unique name of bus connection"),
@@ -290,6 +295,22 @@ g_dbus_connection_class_init (GDBusConnectionClass *klass)
G_PARAM_STATIC_NICK));
/**
+ * GDBusConnection:is-opening:
+ *
+ * A boolean specifying whether the connection is currently being opened.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_IS_OPENING,
+ g_param_spec_boolean ("is-opening",
+ _("is-opening"),
+ _("Whether the connection is being opened"),
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_BLURB |
+ G_PARAM_STATIC_NICK));
+
+ /**
* GDBusConnection:exit-on-close:
*
* A boolean specifying whether _exit() should be called when the
@@ -346,6 +367,7 @@ g_dbus_connection_init (GDBusConnection *connection)
{
connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection, G_TYPE_DBUS_CONNECTION, GDBusConnectionPrivate);
connection->priv->in_init_phase = TRUE;
+ connection->priv->init_phase_pending_simple_async_results = g_ptr_array_new ();
}
/**
@@ -395,6 +417,22 @@ g_dbus_connection_get_is_open (GDBusConnection *connection)
}
/**
+ * g_dbus_connection_get_is_opening:
+ * @connection: A #GDBusConnection.
+ *
+ * Gets whether a connection is currently opening.
+ *
+ * Returns: %TRUE if the connection is currently opening, %FALSE otherwise.
+ **/
+gboolean
+g_dbus_connection_get_is_opening (GDBusConnection *connection)
+{
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
+
+ return connection->priv->in_init_phase;
+}
+
+/**
* g_dbus_connection_get_dbus_1_connection:
* @connection: A #GDBusConnection.
*
@@ -647,8 +685,12 @@ open_bus_connection (gpointer user_data)
}
connection->priv->in_init_phase = FALSE;
g_ptr_array_free (connection->priv->init_phase_pending_simple_async_results, TRUE);
+ connection->priv->init_phase_pending_simple_async_results = NULL;
G_UNLOCK (connection_lock);
+ /* let others know that they can now trust g_dbus_connection_get_is_open() */
+ g_object_notify (G_OBJECT (connection), "is-opening");
+
return FALSE;
}
@@ -774,7 +816,6 @@ g_dbus_connection_bus_get_internal (GMessageBusType bus_type,
callback,
user_data,
private ? g_dbus_connection_bus_get_private_finish : g_dbus_connection_bus_get_finish);
- connection->priv->init_phase_pending_simple_async_results = g_ptr_array_new ();
g_ptr_array_add (connection->priv->init_phase_pending_simple_async_results, simple);
G_UNLOCK (connection_lock);
diff --git a/gdbus/gdbusconnection.h b/gdbus/gdbusconnection.h
index a1688f1..fe97ae7 100644
--- a/gdbus/gdbusconnection.h
+++ b/gdbus/gdbusconnection.h
@@ -105,6 +105,7 @@ gboolean g_dbus_connection_bus_get_private_finish (GDBusConnection *
GMessageBusType g_dbus_connection_get_bus_type (GDBusConnection *connection);
gboolean g_dbus_connection_get_is_open (GDBusConnection *connection);
+gboolean g_dbus_connection_get_is_opening (GDBusConnection *connection);
DBusConnection *g_dbus_connection_get_dbus_1_connection (GDBusConnection *connection);
const gchar *g_dbus_connection_get_unique_name (GDBusConnection *connection);
gboolean g_dbus_connection_get_exit_on_close (GDBusConnection *connection);
diff --git a/gdbus/tests/connection.c b/gdbus/tests/connection.c
index 05118f9..0190275 100644
--- a/gdbus/tests/connection.c
+++ b/gdbus/tests/connection.c
@@ -659,6 +659,7 @@ on_owner_cb_expect_failure (GBusNameOwner *owner,
_g_assert_error_domain (error, G_DBUS_ERROR);
g_error_free (error);
g_assert (!ret);
+ g_assert (!g_bus_name_owner_get_owns_name (owner));
*val = TRUE;
g_main_loop_quit (loop);
@@ -697,6 +698,7 @@ on_owner_cb_expect_success (GBusNameOwner *owner,
&error);
g_assert_no_error (error);
g_assert (ret);
+ g_assert (g_bus_name_owner_get_owns_name (owner));
*val = TRUE;
g_main_loop_quit (loop);
@@ -743,16 +745,15 @@ on_owner_cb_expect_failure2 (GBusNameOwner *owner,
ret = g_bus_name_owner_new_finish (owner,
result,
&error);
- g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED);
- g_error_free (error);
- g_assert (!ret);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert (!g_bus_name_owner_get_owns_name (owner));
*val = TRUE;
g_main_loop_quit (loop);
}
/* ---------------------------------------------------------------------------------------------------- */
-
static void
on_owner_for_connection_cb_expect_failure (GBusNameOwner *owner,
GAsyncResult *result,
@@ -766,14 +767,13 @@ on_owner_for_connection_cb_expect_failure (GBusNameOwner *owner,
ret = g_bus_name_owner_new_for_connection_finish (owner,
result,
&error);
- g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED);
- g_error_free (error);
- g_assert (!ret);
+ g_assert_no_error (error);
+ g_assert (ret);
+ g_assert (!g_bus_name_owner_get_owns_name (owner));
*val = TRUE;
g_main_loop_quit (loop);
}
-
/* ---------------------------------------------------------------------------------------------------- */
static void
@@ -841,15 +841,18 @@ test_bus_name_owner (void)
g_assert (val);
g_assert (val2);
- /* try owning the same name again... the should fail because o is still alive */
+ /* try owning the same name again... this should not fail, we should get the same object
+ * as o because of singleton handling
+ */
o2 = g_bus_name_owner_new (G_MESSAGE_BUS_TYPE_SESSION,
"org.gtk.Test.Name1",
G_BUS_NAME_OWNER_FLAGS_NONE,
NULL,
- (GAsyncReadyCallback) on_owner_cb_expect_failure2,
+ (GAsyncReadyCallback) on_owner_cb_expect_success,
&val);
g_main_loop_run (loop);
g_assert (val);
+ g_assert (o2 == o);
g_object_unref (o2);
/* now kill o.. and then attempt to own the same name again.. */
@@ -895,6 +898,9 @@ test_bus_name_owner (void)
(GAsyncReadyCallback) get_connection_callback_private,
NULL); /* user_data */
g_main_loop_run (loop);
+ g_debug ("orig %s, private %s",
+ g_dbus_connection_get_unique_name (g_bus_name_owner_get_connection (o)),
+ g_dbus_connection_get_unique_name (private_connection));
val = FALSE;
o2 = g_bus_name_owner_new_for_connection (private_connection,
"org.gtk.Test.Name1",
@@ -968,15 +974,16 @@ bnw_cb_expect_error (GBusNameWatcher *watcher,
gpointer user_data)
{
GError *error;
- gboolean has_name_owner;
+ gboolean ret;
error = NULL;
- has_name_owner = g_bus_name_watcher_new_finish (watcher,
- res,
- &error);
+ ret = g_bus_name_watcher_new_finish (watcher,
+ res,
+ &error);
_g_assert_error_domain (error, G_DBUS_ERROR);
g_error_free (error);
- g_assert (!has_name_owner);
+ g_assert (!ret);
+ g_assert_cmpstr (g_bus_name_watcher_get_name_owner (watcher), ==, NULL);
g_main_loop_quit (loop);
}
@@ -989,14 +996,15 @@ bnw_cb_expect_null_owner (GBusNameWatcher *watcher,
gpointer user_data)
{
GError *error;
- gboolean has_name_owner;
+ gboolean ret;
error = NULL;
- has_name_owner = g_bus_name_watcher_new_finish (watcher,
- res,
- &error);
- g_assert_no_error (error);
- g_assert (!has_name_owner);
+ ret = g_bus_name_watcher_new_finish (watcher,
+ res,
+ &error);
+ _g_assert_error_domain (error, G_DBUS_ERROR);
+ g_assert (!ret);
+ g_assert_cmpstr (g_bus_name_watcher_get_name_owner (watcher), ==, NULL);
g_main_loop_quit (loop);
}
@@ -1004,7 +1012,7 @@ bnw_cb_expect_null_owner (GBusNameWatcher *watcher,
/* ---------------------------------------------------------------------------------------------------- */
static void
-nbw_on_owner_cb_expect_success (GBusNameOwner *owner,
+bnw_on_owner_cb_expect_success (GBusNameOwner *owner,
GAsyncResult *result,
gpointer user_data)
{
@@ -1017,6 +1025,7 @@ nbw_on_owner_cb_expect_success (GBusNameOwner *owner,
&error);
g_assert_no_error (error);
g_assert (ret);
+ g_assert (g_bus_name_owner_get_owns_name (owner));
g_main_loop_quit (loop);
}
@@ -1029,14 +1038,15 @@ bnw_cb_expect_owner (GBusNameWatcher *watcher,
gpointer user_data)
{
GError *error;
- gboolean has_name_owner;
+ gboolean ret;
error = NULL;
- has_name_owner = g_bus_name_watcher_new_finish (watcher,
- res,
- &error);
+ ret = g_bus_name_watcher_new_finish (watcher,
+ res,
+ &error);
g_assert_no_error (error);
- g_assert (has_name_owner);
+ g_assert (ret);
+ g_assert_cmpstr (g_bus_name_watcher_get_name_owner (watcher), !=, NULL);
g_main_loop_quit (loop);
}
@@ -1068,14 +1078,15 @@ bnw_cb_singleton (GBusNameWatcher *watcher,
{
gboolean *val = user_data;
GError *error;
- gboolean has_name_owner;
+ gboolean ret;
error = NULL;
- has_name_owner = g_bus_name_watcher_new_finish (watcher,
- res,
- &error);
+ ret = g_bus_name_watcher_new_finish (watcher,
+ res,
+ &error);
g_assert_no_error (error);
- g_assert (has_name_owner);
+ g_assert (ret);
+ g_assert_cmpstr (g_bus_name_watcher_get_name_owner (watcher), !=, NULL);
*val = TRUE;
@@ -1092,7 +1103,7 @@ test_bus_name_watcher (void)
GBusNameOwner *o;
gboolean val;
- /* if no session bus is available, expect the callback to fail */
+ /* if no session bus is available, expect the callback to expect an error */
w = g_bus_name_watcher_new (G_MESSAGE_BUS_TYPE_SESSION,
"org.gtk.Test.Name1",
NULL,
@@ -1102,7 +1113,7 @@ test_bus_name_watcher (void)
g_dbus_connection_set_exit_on_close (g_bus_name_watcher_get_connection (w), FALSE);
g_object_unref (w);
- /* if a session bus is available, expect the callback to succeed with name_owner==NULL */
+ /* if a session bus is available, expect the callback to fail */
session_bus_up ();
w = g_bus_name_watcher_new (G_MESSAGE_BUS_TYPE_SESSION,
"org.gtk.Test.Name1",
@@ -1118,7 +1129,7 @@ test_bus_name_watcher (void)
"org.gtk.Test.Name1",
G_BUS_NAME_OWNER_FLAGS_NONE,
NULL,
- (GAsyncReadyCallback) nbw_on_owner_cb_expect_success,
+ (GAsyncReadyCallback) bnw_on_owner_cb_expect_success,
NULL);
g_main_loop_run (loop);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]