X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgdbusnameowning.c;h=d39faea32b09393329930693dca9b73d7a8005ba;hb=472e727299d0525c82b6df97d557d2bf8cf915de;hp=65b1227cf74e9f4ffe27430ec5b1c3bf0d366e17;hpb=8d3250016dac9d43b2a2de6dacb670a9fbc88808;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c index 65b1227..d39faea 100644 --- a/gio/gdbusnameowning.c +++ b/gio/gdbusnameowning.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: David Zeuthen */ @@ -30,6 +28,10 @@ #include "gdbusprivate.h" #include "gdbusconnection.h" +#ifdef G_OS_UNIX +#include "gkdbusconnection.h" +#endif + #include "glibintl.h" /** @@ -40,7 +42,8 @@ * * Convenience API for owning bus names. * - * Simple application owning a nameFIXME: MISSING XINCLUDE CONTENT + * A simple example for owning a name can be found in + * [gdbus-example-own-name.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-own-name.c) */ G_LOCK_DEFINE_STATIC (lock); @@ -74,7 +77,7 @@ typedef struct guint name_acquired_subscription_id; guint name_lost_subscription_id; - gboolean cancelled; + volatile gboolean cancelled; /* must hold lock when reading or modifying */ gboolean needs_release; } Client; @@ -198,6 +201,7 @@ schedule_call_in_idle (Client *client, CallType call_type) call_in_idle_cb, data, (GDestroyNotify) call_handler_data_free); + g_source_set_name (idle_source, "[gio] call_in_idle_cb"); g_source_attach (idle_source, client->main_context); g_source_unref (idle_source); } @@ -219,27 +223,39 @@ do_call (Client *client, CallType call_type) static void call_acquired_handler (Client *client) { + G_LOCK (lock); if (client->previous_call != PREVIOUS_CALL_ACQUIRED) { client->previous_call = PREVIOUS_CALL_ACQUIRED; if (!client->cancelled) { + G_UNLOCK (lock); do_call (client, CALL_TYPE_NAME_ACQUIRED); + goto out; } } + G_UNLOCK (lock); + out: + ; } static void call_lost_handler (Client *client) { + G_LOCK (lock); if (client->previous_call != PREVIOUS_CALL_LOST) { client->previous_call = PREVIOUS_CALL_LOST; if (!client->cancelled) { + G_UNLOCK (lock); do_call (client, CALL_TYPE_NAME_LOST); + goto out; } } + G_UNLOCK (lock); + out: + ; } /* ---------------------------------------------------------------------------------------------------- */ @@ -284,27 +300,11 @@ on_name_lost_or_acquired (GDBusConnection *connection, /* ---------------------------------------------------------------------------------------------------- */ static void -request_name_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +process_request_name_reply (Client *client, + guint32 request_name_reply) { - Client *client = user_data; - GVariant *result; - guint32 request_name_reply; gboolean subscribe; - request_name_reply = 0; - result = NULL; - - result = g_dbus_connection_call_finish (client->connection, - res, - NULL); - if (result != NULL) - { - g_variant_get (result, "(u)", &request_name_reply); - g_variant_unref (result); - } - subscribe = FALSE; switch (request_name_reply) @@ -332,33 +332,76 @@ request_name_cb (GObject *source_object, break; } + if (subscribe) { + GDBusConnection *connection = NULL; + + /* if cancelled, there is no point in subscribing to signals - if not, make sure + * we use a known good Connection object since it may be set to NULL at any point + * after being cancelled + */ + G_LOCK (lock); + if (!client->cancelled) + connection = g_object_ref (client->connection); + G_UNLOCK (lock); + /* start listening to NameLost and NameAcquired messages */ - client->name_lost_subscription_id = - g_dbus_connection_signal_subscribe (client->connection, - "org.freedesktop.DBus", - "org.freedesktop.DBus", - "NameLost", - "/org/freedesktop/DBus", - client->name, - G_DBUS_SIGNAL_FLAGS_NONE, - on_name_lost_or_acquired, - client, - NULL); - client->name_acquired_subscription_id = - g_dbus_connection_signal_subscribe (client->connection, - "org.freedesktop.DBus", - "org.freedesktop.DBus", - "NameAcquired", - "/org/freedesktop/DBus", - client->name, - G_DBUS_SIGNAL_FLAGS_NONE, - on_name_lost_or_acquired, - client, - NULL); + if (connection != NULL) + { + client->name_lost_subscription_id = + g_dbus_connection_signal_subscribe (connection, + "org.freedesktop.DBus", + "org.freedesktop.DBus", + "NameLost", + "/org/freedesktop/DBus", + client->name, + G_DBUS_SIGNAL_FLAGS_NONE, + on_name_lost_or_acquired, + client, + NULL); + client->name_acquired_subscription_id = + g_dbus_connection_signal_subscribe (connection, + "org.freedesktop.DBus", + "org.freedesktop.DBus", + "NameAcquired", + "/org/freedesktop/DBus", + client->name, + G_DBUS_SIGNAL_FLAGS_NONE, + on_name_lost_or_acquired, + client, + NULL); + g_object_unref (connection); + } + } +} + +/* ---------------------------------------------------------------------------------------------------- */ + +static void +request_name_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + Client *client = user_data; + GVariant *result; + guint32 request_name_reply; + + request_name_reply = 0; + result = NULL; + + /* don't use client->connection - it may be NULL already */ + result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), + res, + NULL); + if (result != NULL) + { + g_variant_get (result, "(u)", &request_name_reply); + g_variant_unref (result); } + process_request_name_reply (client, request_name_reply); + client_unref (client); } @@ -399,20 +442,41 @@ has_connection (Client *client) client); /* attempt to acquire the name */ - g_dbus_connection_call (client->connection, - "org.freedesktop.DBus", /* bus name */ - "/org/freedesktop/DBus", /* object path */ - "org.freedesktop.DBus", /* interface name */ - "RequestName", /* method name */ - g_variant_new ("(su)", - client->name, - client->flags), - G_VARIANT_TYPE ("(u)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - (GAsyncReadyCallback) request_name_cb, - client_ref (client)); + if (G_IS_KDBUS_CONNECTION (g_dbus_connection_get_stream (client->connection))) + { + GVariant *result; + guint32 request_name_reply; + + request_name_reply = 0; + result = NULL; + + result = _g_kdbus_RequestName (client->connection, client->name, client->flags, NULL); + + if (result != NULL) + { + g_variant_get (result, "(u)", &request_name_reply); + g_variant_unref (result); + } + + process_request_name_reply (client, request_name_reply); + } + else + { + g_dbus_connection_call (client->connection, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "RequestName", /* method name */ + g_variant_new ("(su)", + client->name, + client->flags), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) request_name_cb, + client_ref (client)); + } } @@ -423,6 +487,15 @@ connection_get_cb (GObject *source_object, { Client *client = user_data; + /* must not do anything if already cancelled */ + G_LOCK (lock); + if (client->cancelled) + { + G_UNLOCK (lock); + goto out; + } + G_UNLOCK (lock); + client->connection = g_bus_get_finish (res, NULL); if (client->connection == NULL) { @@ -454,19 +527,19 @@ connection_get_cb (GObject *source_object, /** * g_bus_own_name_on_connection: - * @connection: A #GDBusConnection. - * @name: The well-known name to own. - * @flags: A set of flags from the #GBusNameOwnerFlags enumeration. - * @name_acquired_handler: Handler to invoke when @name is acquired or %NULL. - * @name_lost_handler: Handler to invoke when @name is lost or %NULL. - * @user_data: User data to pass to handlers. - * @user_data_free_func: Function for freeing @user_data or %NULL. + * @connection: a #GDBusConnection + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration + * @name_acquired_handler: (allow-none): handler to invoke when @name is acquired or %NULL + * @name_lost_handler: (allow-none): handler to invoke when @name is lost or %NULL + * @user_data: user data to pass to handlers + * @user_data_free_func: (allow-none): function for freeing @user_data or %NULL * * Like g_bus_own_name() but takes a #GDBusConnection instead of a * #GBusType. * - * Returns: An identifier (never 0) that an be used with - * g_bus_unown_name() to stop owning the name. + * Returns: an identifier (never 0) that an be used with + * g_bus_unown_name() to stop owning the name * * Since: 2.26 */ @@ -516,44 +589,43 @@ g_bus_own_name_on_connection (GDBusConnection *connection, /** * g_bus_own_name: - * @bus_type: The type of bus to own a name on. - * @name: The well-known name to own. - * @flags: A set of flags from the #GBusNameOwnerFlags enumeration. - * @bus_acquired_handler: Handler to invoke when connected to the bus of type @bus_type or %NULL. - * @name_acquired_handler: Handler to invoke when @name is acquired or %NULL. - * @name_lost_handler: Handler to invoke when @name is lost or %NULL. - * @user_data: User data to pass to handlers. - * @user_data_free_func: Function for freeing @user_data or %NULL. + * @bus_type: the type of bus to own a name on + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration + * @bus_acquired_handler: (allow-none): handler to invoke when connected to the bus of type @bus_type or %NULL + * @name_acquired_handler: (allow-none): handler to invoke when @name is acquired or %NULL + * @name_lost_handler: (allow-none): handler to invoke when @name is lost or %NULL + * @user_data: user data to pass to handlers + * @user_data_free_func: (allow-none): function for freeing @user_data or %NULL * * Starts acquiring @name on the bus specified by @bus_type and calls * @name_acquired_handler and @name_lost_handler when the name is - * acquired respectively lost. Callbacks will be invoked in the thread-default main - * loop of the thread you are calling this function from. + * acquired respectively lost. Callbacks will be invoked in the + * [thread-default main context][g-main-context-push-thread-default] + * of the thread you are calling this function from. * * You are guaranteed that one of the @name_acquired_handler and @name_lost_handler * callbacks will be invoked after calling this function - there are three * possible cases: - * - * - * @name_lost_handler with a %NULL connection (if a connection to the bus can't be made). - * - * - * @bus_acquired_handler then @name_lost_handler (if the name can't be obtained) - * - * - * @bus_acquired_handler then @name_acquired_handler (if the name was obtained). - * - * + * + * - @name_lost_handler with a %NULL connection (if a connection to the bus + * can't be made). + * + * - @bus_acquired_handler then @name_lost_handler (if the name can't be + * obtained) + * + * - @bus_acquired_handler then @name_acquired_handler (if the name was + * obtained). + * * When you are done owning the name, just call g_bus_unown_name() * with the owner id this function returns. * * If the name is acquired or lost (for example another application * could acquire the name if you allow replacement or the application - * currently owning the name exits), the handlers are also invoked. If the - * #GDBusConnection that is used for attempting to own the name - * closes, then @name_lost_handler is invoked since it is no - * longer possible for other processes to access the process. + * currently owning the name exits), the handlers are also invoked. + * If the #GDBusConnection that is used for attempting to own the name + * closes, then @name_lost_handler is invoked since it is no longer + * possible for other processes to access the process. * * You cannot use g_bus_own_name() several times for the same name (unless * interleaved with calls to g_bus_unown_name()) - only the first call @@ -572,12 +644,12 @@ g_bus_own_name_on_connection (GDBusConnection *connection, * before @name is requested from the bus. * * This behavior makes it very simple to write applications that wants - * to own names and export objects, see . + * to [own names][gdbus-owning-names] and export objects. * Simply register objects to be exported in @bus_acquired_handler and * unregister the objects (if any) in @name_lost_handler. * - * Returns: An identifier (never 0) that an be used with - * g_bus_unown_name() to stop owning the name. + * Returns: an identifier (never 0) that an be used with + * g_bus_unown_name() to stop owning the name. * * Since: 2.26 */ @@ -748,33 +820,33 @@ bus_own_name_free_func (gpointer user_data) /** * g_bus_own_name_with_closures: - * @bus_type: The type of bus to own a name on. - * @name: The well-known name to own. - * @flags: A set of flags from the #GBusNameOwnerFlags enumeration. + * @bus_type: the type of bus to own a name on + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration * @bus_acquired_closure: (allow-none): #GClosure to invoke when connected to - * the bus of type @bus_type or %NULL. + * the bus of type @bus_type or %NULL * @name_acquired_closure: (allow-none): #GClosure to invoke when @name is - * acquired or %NULL. + * acquired or %NULL * @name_lost_closure: (allow-none): #GClosure to invoke when @name is lost or - * %NULL. + * %NULL * * Version of g_bus_own_name() using closures instead of callbacks for * easier binding in other languages. * - * Returns: An identifier (never 0) that an be used with - * g_bus_unown_name() to stop owning the name. + * Returns: an identifier (never 0) that an be used with + * g_bus_unown_name() to stop owning the name. * * Rename to: g_bus_own_name * * Since: 2.26 */ guint -g_bus_own_name_with_closures (GBusType bus_type, - const gchar *name, - GBusNameOwnerFlags flags, - GClosure *bus_acquired_closure, - GClosure *name_acquired_closure, - GClosure *name_lost_closure) +g_bus_own_name_with_closures (GBusType bus_type, + const gchar *name, + GBusNameOwnerFlags flags, + GClosure *bus_acquired_closure, + GClosure *name_acquired_closure, + GClosure *name_lost_closure) { return g_bus_own_name (bus_type, name, @@ -790,30 +862,30 @@ g_bus_own_name_with_closures (GBusType bus_type, /** * g_bus_own_name_on_connection_with_closures: - * @connection: A #GDBusConnection. - * @name: The well-known name to own. - * @flags: A set of flags from the #GBusNameOwnerFlags enumeration. + * @connection: a #GDBusConnection + * @name: the well-known name to own + * @flags: a set of flags from the #GBusNameOwnerFlags enumeration * @name_acquired_closure: (allow-none): #GClosure to invoke when @name is - * acquired or %NULL. - * @name_lost_closure: (allow-none): #GClosure to invoke when @name is lost or - * %NULL. + * acquired or %NULL + * @name_lost_closure: (allow-none): #GClosure to invoke when @name is lost + * or %NULL * - * Version of g_bus_own_name_on_connection() using closures instead of callbacks for - * easier binding in other languages. + * Version of g_bus_own_name_on_connection() using closures instead of + * callbacks for easier binding in other languages. * - * Returns: An identifier (never 0) that an be used with - * g_bus_unown_name() to stop owning the name. + * Returns: an identifier (never 0) that an be used with + * g_bus_unown_name() to stop owning the name. * * Rename to: g_bus_own_name_on_connection * * Since: 2.26 */ guint -g_bus_own_name_on_connection_with_closures (GDBusConnection *connection, - const gchar *name, - GBusNameOwnerFlags flags, - GClosure *name_acquired_closure, - GClosure *name_lost_closure) +g_bus_own_name_on_connection_with_closures (GDBusConnection *connection, + const gchar *name, + GBusNameOwnerFlags flags, + GClosure *name_acquired_closure, + GClosure *name_lost_closure) { return g_bus_own_name_on_connection (connection, name, @@ -828,7 +900,7 @@ g_bus_own_name_on_connection_with_closures (GDBusConnection *connection /** * g_bus_unown_name: - * @owner_id: An identifier obtained from g_bus_own_name() + * @owner_id: an identifier obtained from g_bus_own_name() * * Stops owning a name. * @@ -861,7 +933,9 @@ g_bus_unown_name (guint owner_id) if (client != NULL) { /* Release the name if needed */ - if (client->needs_release && client->connection != NULL) + if (client->needs_release && + client->connection != NULL && + !g_dbus_connection_is_closed (client->connection)) { GVariant *result; GError *error; @@ -874,17 +948,20 @@ g_bus_unown_name (guint owner_id) * I believe this is a bug in the bus daemon. */ error = NULL; - result = g_dbus_connection_call_sync (client->connection, - "org.freedesktop.DBus", /* bus name */ - "/org/freedesktop/DBus", /* object path */ - "org.freedesktop.DBus", /* interface name */ - "ReleaseName", /* method name */ - g_variant_new ("(s)", client->name), - G_VARIANT_TYPE ("(u)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); + if (G_IS_KDBUS_CONNECTION (g_dbus_connection_get_stream (client->connection))) + result = _g_kdbus_ReleaseName (client->connection, client->name, &error); + else + result = g_dbus_connection_call_sync (client->connection, + "org.freedesktop.DBus", /* bus name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "ReleaseName", /* method name */ + g_variant_new ("(s)", client->name), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); if (result == NULL) { g_warning ("Error releasing name %s: %s", client->name, error->message);