X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgdbusnameowning.c;h=cb7cb09a19661a766504771d97990b686b88492a;hb=174ebaefcc2b1b94f4a628e60f150b7209230dbf;hp=9356d923a5ab1da9584fadc1bc7a074cb78bbdd4;hpb=5b946e0504952a472cea1ef95df0967e8a4a7b47;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c index 9356d92..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 */ @@ -40,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); @@ -74,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; @@ -105,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); @@ -199,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); } @@ -206,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: + ; } /* ---------------------------------------------------------------------------------------------------- */ @@ -293,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) @@ -329,29 +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, - 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, - 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); @@ -418,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) { @@ -449,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 */ @@ -490,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); @@ -513,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 @@ -569,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 */ @@ -604,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) { @@ -632,13 +670,49 @@ typedef struct { GClosure *name_lost_closure; } OwnNameData; +static OwnNameData * +own_name_data_new (GClosure *bus_acquired_closure, + GClosure *name_acquired_closure, + GClosure *name_lost_closure) +{ + OwnNameData *data; + + data = g_new0 (OwnNameData, 1); + + if (bus_acquired_closure != NULL) + { + 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, g_cclosure_marshal_generic); + } + + if (name_acquired_closure != NULL) + { + 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, g_cclosure_marshal_generic); + } + + if (name_lost_closure != NULL) + { + 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, g_cclosure_marshal_generic); + } + + return data; +} + static void own_with_closures_on_bus_acquired (GDBusConnection *connection, const gchar *name, 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); @@ -647,6 +721,9 @@ own_with_closures_on_bus_acquired (GDBusConnection *connection, g_value_set_string (¶ms[1], name); g_closure_invoke (data->bus_acquired_closure, NULL, 2, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); } static void @@ -655,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); @@ -664,6 +741,9 @@ own_with_closures_on_name_acquired (GDBusConnection *connection, g_value_set_string (¶ms[1], name); g_closure_invoke (data->name_acquired_closure, NULL, 2, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); } static void @@ -672,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); @@ -681,6 +761,9 @@ own_with_closures_on_name_lost (GDBusConnection *connection, g_value_set_string (¶ms[1], name); g_closure_invoke (data->name_lost_closure, NULL, 2, params, NULL); + + g_value_unset (params + 0); + g_value_unset (params + 1); } static void @@ -702,121 +785,87 @@ 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) { - OwnNameData *data; - - data = g_new0 (OwnNameData, 1); - - if (bus_acquired_closure != NULL) - { - data->bus_acquired_closure = g_closure_ref (bus_acquired_closure); - g_closure_sink (bus_acquired_closure); - } - - if (name_acquired_closure != NULL) - { - data->name_acquired_closure = g_closure_ref (name_acquired_closure); - g_closure_sink (name_acquired_closure); - } - - if (name_lost_closure != NULL) - { - data->name_lost_closure = g_closure_ref (name_lost_closure); - g_closure_sink (name_lost_closure); - } - return g_bus_own_name (bus_type, name, flags, bus_acquired_closure != NULL ? own_with_closures_on_bus_acquired : NULL, name_acquired_closure != NULL ? own_with_closures_on_name_acquired : NULL, name_lost_closure != NULL ? own_with_closures_on_name_lost : NULL, - data, + own_name_data_new (bus_acquired_closure, + name_acquired_closure, + name_lost_closure), bus_own_name_free_func); } /** * 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) { - OwnNameData *data; - - data = g_new0 (OwnNameData, 1); - - if (name_acquired_closure != NULL) - { - data->name_acquired_closure = g_closure_ref (name_acquired_closure); - g_closure_sink (name_acquired_closure); - } - - if (name_lost_closure != NULL) - { - data->name_lost_closure = g_closure_ref (name_lost_closure); - g_closure_sink (name_lost_closure); - } - return g_bus_own_name_on_connection (connection, name, flags, name_acquired_closure != NULL ? own_with_closures_on_name_acquired : NULL, name_lost_closure != NULL ? own_with_closures_on_name_lost : NULL, - data, + own_name_data_new (NULL, + name_acquired_closure, + name_lost_closure), bus_own_name_free_func); } /** * 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. * @@ -849,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;