X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=gio%2Fgdbusnameowning.c;h=cb7cb09a19661a766504771d97990b686b88492a;hb=c8d10470939847069b1a346d4c44f2adde3469f6;hp=6a5dc84620df2c21d6c8618fbb44c205090a40d3;hpb=d8ca6404229e5b64d2bf2e1a3660ad9fe7feefdd;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c index 6a5dc84..cb7cb09 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 */ @@ -29,7 +27,6 @@ #include "gdbuserror.h" #include "gdbusprivate.h" #include "gdbusconnection.h" -#include "gio-marshal.h" #include "glibintl.h" @@ -41,7 +38,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); @@ -75,7 +73,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; @@ -106,8 +104,7 @@ client_unref (Client *client) g_dbus_connection_signal_unsubscribe (client->connection, client->name_lost_subscription_id); g_object_unref (client->connection); } - if (client->main_context != NULL) - g_main_context_unref (client->main_context); + g_main_context_unref (client->main_context); g_free (client->name); if (client->user_data_free_func != NULL) client->user_data_free_func (client->user_data); @@ -200,6 +197,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); } @@ -207,37 +205,53 @@ schedule_call_in_idle (Client *client, CallType call_type) static void do_call (Client *client, CallType call_type) { + GMainContext *current_context; + /* only schedule in idle if we're not in the right thread */ - if (g_main_context_get_thread_default () != client->main_context) + current_context = g_main_context_ref_thread_default (); + if (current_context != client->main_context) schedule_call_in_idle (client, call_type); else actually_do_call (client, client->connection, call_type); + g_main_context_unref (current_context); } 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: + ; } /* ---------------------------------------------------------------------------------------------------- */ @@ -294,7 +308,8 @@ request_name_cb (GObject *source_object, request_name_reply = 0; result = NULL; - result = g_dbus_connection_call_finish (client->connection, + /* 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) @@ -330,31 +345,47 @@ 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); + } } client_unref (client); @@ -421,6 +452,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) { @@ -452,19 +492,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 */ @@ -493,9 +533,7 @@ g_bus_own_name_on_connection (GDBusConnection *connection, client->name_lost_handler = name_lost_handler; client->user_data = user_data; client->user_data_free_func = user_data_free_func; - client->main_context = g_main_context_get_thread_default (); - if (client->main_context != NULL) - g_main_context_ref (client->main_context); + client->main_context = g_main_context_ref_thread_default (); client->connection = g_object_ref (connection); @@ -516,44 +554,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 +609,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 */ @@ -607,9 +644,7 @@ g_bus_own_name (GBusType bus_type, client->name_lost_handler = name_lost_handler; client->user_data = user_data; client->user_data_free_func = user_data_free_func; - client->main_context = g_main_context_get_thread_default (); - if (client->main_context != NULL) - g_main_context_ref (client->main_context); + client->main_context = g_main_context_ref_thread_default (); if (map_id_to_client == NULL) { @@ -649,7 +684,7 @@ own_name_data_new (GClosure *bus_acquired_closure, data->bus_acquired_closure = g_closure_ref (bus_acquired_closure); g_closure_sink (bus_acquired_closure); if (G_CLOSURE_NEEDS_MARSHAL (bus_acquired_closure)) - g_closure_set_marshal (bus_acquired_closure, _gio_marshal_VOID__STRING); + g_closure_set_marshal (bus_acquired_closure, g_cclosure_marshal_generic); } if (name_acquired_closure != NULL) @@ -657,7 +692,7 @@ own_name_data_new (GClosure *bus_acquired_closure, data->name_acquired_closure = g_closure_ref (name_acquired_closure); g_closure_sink (name_acquired_closure); if (G_CLOSURE_NEEDS_MARSHAL (name_acquired_closure)) - g_closure_set_marshal (name_acquired_closure, _gio_marshal_VOID__STRING); + g_closure_set_marshal (name_acquired_closure, g_cclosure_marshal_generic); } if (name_lost_closure != NULL) @@ -665,7 +700,7 @@ own_name_data_new (GClosure *bus_acquired_closure, data->name_lost_closure = g_closure_ref (name_lost_closure); g_closure_sink (name_lost_closure); if (G_CLOSURE_NEEDS_MARSHAL (name_lost_closure)) - g_closure_set_marshal (name_lost_closure, _gio_marshal_VOID__STRING); + g_closure_set_marshal (name_lost_closure, g_cclosure_marshal_generic); } return data; @@ -677,7 +712,7 @@ own_with_closures_on_bus_acquired (GDBusConnection *connection, gpointer user_data) { OwnNameData *data = user_data; - GValue params[2] = { { 0, }, { 0, } }; + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); g_value_set_object (¶ms[0], connection); @@ -697,7 +732,7 @@ own_with_closures_on_name_acquired (GDBusConnection *connection, gpointer user_data) { OwnNameData *data = user_data; - GValue params[2] = { { 0, }, { 0, } }; + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); g_value_set_object (¶ms[0], connection); @@ -717,7 +752,7 @@ own_with_closures_on_name_lost (GDBusConnection *connection, gpointer user_data) { OwnNameData *data = user_data; - GValue params[2] = { { 0, }, { 0, } }; + GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); g_value_set_object (¶ms[0], connection); @@ -750,33 +785,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, @@ -792,30 +827,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, @@ -830,7 +865,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. * @@ -863,7 +898,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;