| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | /* GDBus - GLib D-Bus Library
 | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-05-09 13:14:55 -04:00
										 |  |  |  |  * Copyright (C) 2008-2010 Red Hat, Inc. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * You should have received a copy of the GNU Lesser General | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Author: David Zeuthen <davidz@redhat.com> | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #include "config.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #include "gdbusutils.h"
 | 
					
						
							|  |  |  |  | #include "gdbusnameowning.h"
 | 
					
						
							|  |  |  |  | #include "gdbuserror.h"
 | 
					
						
							|  |  |  |  | #include "gdbusprivate.h"
 | 
					
						
							|  |  |  |  | #include "gdbusconnection.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 16:34:23 -04:00
										 |  |  |  | #include "glibintl.h"
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | G_LOCK_DEFINE_STATIC (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* ---------------------------------------------------------------------------------------------------- */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef enum | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   PREVIOUS_CALL_NONE = 0, | 
					
						
							|  |  |  |  |   PREVIOUS_CALL_ACQUIRED, | 
					
						
							|  |  |  |  |   PREVIOUS_CALL_LOST, | 
					
						
							|  |  |  |  | } PreviousCall; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef struct | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-11 18:28:23 +00:00
										 |  |  |  |   gint                      ref_count;  /* (atomic) */ | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   guint                     id; | 
					
						
							|  |  |  |  |   GBusNameOwnerFlags        flags; | 
					
						
							|  |  |  |  |   gchar                    *name; | 
					
						
							|  |  |  |  |   GBusAcquiredCallback      bus_acquired_handler; | 
					
						
							|  |  |  |  |   GBusNameAcquiredCallback  name_acquired_handler; | 
					
						
							|  |  |  |  |   GBusNameLostCallback      name_lost_handler; | 
					
						
							|  |  |  |  |   gpointer                  user_data; | 
					
						
							|  |  |  |  |   GDestroyNotify            user_data_free_func; | 
					
						
							|  |  |  |  |   GMainContext             *main_context; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   PreviousCall              previous_call; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   GDBusConnection          *connection; | 
					
						
							|  |  |  |  |   gulong                    disconnected_signal_handler_id; | 
					
						
							|  |  |  |  |   guint                     name_acquired_subscription_id; | 
					
						
							|  |  |  |  |   guint                     name_lost_subscription_id; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-11 18:28:23 +00:00
										 |  |  |  |   gboolean                  cancelled; /* must hold lock when reading or modifying */ | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   gboolean                  needs_release; | 
					
						
							|  |  |  |  | } Client; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static guint next_global_id = 1; | 
					
						
							|  |  |  |  | static GHashTable *map_id_to_client = NULL; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static Client * | 
					
						
							|  |  |  |  | client_ref (Client *client) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   g_atomic_int_inc (&client->ref_count); | 
					
						
							|  |  |  |  |   return client; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | client_unref (Client *client) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   if (g_atomic_int_dec_and_test (&client->ref_count)) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       if (client->connection != NULL) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           if (client->disconnected_signal_handler_id > 0) | 
					
						
							|  |  |  |  |             g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); | 
					
						
							|  |  |  |  |           if (client->name_acquired_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |             g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_acquired_subscription_id)); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |           if (client->name_lost_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |             g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_lost_subscription_id)); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |           g_object_unref (client->connection); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-10-05 10:46:57 -04:00
										 |  |  |  |       g_main_context_unref (client->main_context); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       g_free (client->name); | 
					
						
							|  |  |  |  |       if (client->user_data_free_func != NULL) | 
					
						
							|  |  |  |  |         client->user_data_free_func (client->user_data); | 
					
						
							|  |  |  |  |       g_free (client); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* ---------------------------------------------------------------------------------------------------- */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef enum | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   CALL_TYPE_NAME_ACQUIRED, | 
					
						
							|  |  |  |  |   CALL_TYPE_NAME_LOST | 
					
						
							|  |  |  |  | } CallType; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | typedef struct | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* keep this separate because client->connection may
 | 
					
						
							|  |  |  |  |    * be set to NULL after scheduling the call | 
					
						
							|  |  |  |  |    */ | 
					
						
							|  |  |  |  |   GDBusConnection *connection; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* set to TRUE to call acquired */ | 
					
						
							|  |  |  |  |   CallType call_type; | 
					
						
							|  |  |  |  | } CallHandlerData; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | call_handler_data_free (CallHandlerData *data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   if (data->connection != NULL) | 
					
						
							|  |  |  |  |     g_object_unref (data->connection); | 
					
						
							|  |  |  |  |   client_unref (data->client); | 
					
						
							|  |  |  |  |   g_free (data); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | actually_do_call (Client *client, GDBusConnection *connection, CallType call_type) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   switch (call_type) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |     case CALL_TYPE_NAME_ACQUIRED: | 
					
						
							|  |  |  |  |       if (client->name_acquired_handler != NULL) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           client->name_acquired_handler (connection, | 
					
						
							|  |  |  |  |                                          client->name, | 
					
						
							|  |  |  |  |                                          client->user_data); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       break; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     case CALL_TYPE_NAME_LOST: | 
					
						
							|  |  |  |  |       if (client->name_lost_handler != NULL) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           client->name_lost_handler (connection, | 
					
						
							|  |  |  |  |                                      client->name, | 
					
						
							|  |  |  |  |                                      client->user_data); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       break; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     default: | 
					
						
							|  |  |  |  |       g_assert_not_reached (); | 
					
						
							|  |  |  |  |       break; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static gboolean | 
					
						
							|  |  |  |  | call_in_idle_cb (gpointer _data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   CallHandlerData *data = _data; | 
					
						
							|  |  |  |  |   actually_do_call (data->client, data->connection, data->call_type); | 
					
						
							|  |  |  |  |   return FALSE; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | schedule_call_in_idle (Client *client, CallType  call_type) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   CallHandlerData *data; | 
					
						
							|  |  |  |  |   GSource *idle_source; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   data = g_new0 (CallHandlerData, 1); | 
					
						
							|  |  |  |  |   data->client = client_ref (client); | 
					
						
							|  |  |  |  |   data->connection = client->connection != NULL ? g_object_ref (client->connection) : NULL; | 
					
						
							|  |  |  |  |   data->call_type = call_type; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   idle_source = g_idle_source_new (); | 
					
						
							|  |  |  |  |   g_source_set_priority (idle_source, G_PRIORITY_HIGH); | 
					
						
							|  |  |  |  |   g_source_set_callback (idle_source, | 
					
						
							|  |  |  |  |                          call_in_idle_cb, | 
					
						
							|  |  |  |  |                          data, | 
					
						
							|  |  |  |  |                          (GDestroyNotify) call_handler_data_free); | 
					
						
							| 
									
										
										
										
											2021-07-26 10:53:02 +01:00
										 |  |  |  |   g_source_set_static_name (idle_source, "[gio, gdbusnameowning.c] call_in_idle_cb"); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   g_source_attach (idle_source, client->main_context); | 
					
						
							|  |  |  |  |   g_source_unref (idle_source); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | do_call (Client *client, CallType call_type) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-05 10:46:57 -04:00
										 |  |  |  |   GMainContext *current_context; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   /* only schedule in idle if we're not in the right thread */ | 
					
						
							| 
									
										
										
										
											2011-10-05 10:46:57 -04:00
										 |  |  |  |   current_context = g_main_context_ref_thread_default (); | 
					
						
							|  |  |  |  |   if (current_context != client->main_context) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |     schedule_call_in_idle (client, call_type); | 
					
						
							|  |  |  |  |   else | 
					
						
							|  |  |  |  |     actually_do_call (client, client->connection, call_type); | 
					
						
							| 
									
										
										
										
											2011-10-05 10:46:57 -04:00
										 |  |  |  |   g_main_context_unref (current_context); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | call_acquired_handler (Client *client) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |   G_LOCK (lock); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   if (client->previous_call != PREVIOUS_CALL_ACQUIRED) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       client->previous_call = PREVIOUS_CALL_ACQUIRED; | 
					
						
							|  |  |  |  |       if (!client->cancelled) | 
					
						
							|  |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |           G_UNLOCK (lock); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |           do_call (client, CALL_TYPE_NAME_ACQUIRED); | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |           goto out; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |   G_UNLOCK (lock); | 
					
						
							|  |  |  |  |  out: | 
					
						
							|  |  |  |  |   ; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | call_lost_handler (Client  *client) | 
					
						
							|  |  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |   G_LOCK (lock); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   if (client->previous_call != PREVIOUS_CALL_LOST) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       client->previous_call = PREVIOUS_CALL_LOST; | 
					
						
							|  |  |  |  |       if (!client->cancelled) | 
					
						
							|  |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |           G_UNLOCK (lock); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |           do_call (client, CALL_TYPE_NAME_LOST); | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |           goto out; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |   G_UNLOCK (lock); | 
					
						
							|  |  |  |  |  out: | 
					
						
							|  |  |  |  |   ; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* ---------------------------------------------------------------------------------------------------- */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | on_name_lost_or_acquired (GDBusConnection  *connection, | 
					
						
							|  |  |  |  |                           const gchar      *sender_name, | 
					
						
							|  |  |  |  |                           const gchar      *object_path, | 
					
						
							|  |  |  |  |                           const gchar      *interface_name, | 
					
						
							|  |  |  |  |                           const gchar      *signal_name, | 
					
						
							|  |  |  |  |                           GVariant         *parameters, | 
					
						
							|  |  |  |  |                           gpointer          user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client = user_data; | 
					
						
							|  |  |  |  |   const gchar *name; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-13 12:50:42 +01:00
										 |  |  |  |   if (g_strcmp0 (object_path, DBUS_PATH_DBUS) != 0 || | 
					
						
							|  |  |  |  |       g_strcmp0 (interface_name, DBUS_INTERFACE_DBUS) != 0 || | 
					
						
							|  |  |  |  |       g_strcmp0 (sender_name, DBUS_SERVICE_DBUS) != 0) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |     goto out; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 12:47:50 +01:00
										 |  |  |  |   if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)"))) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       g_warning ("%s signal had unexpected signature %s", signal_name, | 
					
						
							|  |  |  |  |                  g_variant_get_type_string (parameters)); | 
					
						
							|  |  |  |  |       goto out; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   if (g_strcmp0 (signal_name, "NameLost") == 0) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-05-13 19:20:26 +02:00
										 |  |  |  |       g_variant_get (parameters, "(&s)", &name); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       if (g_strcmp0 (name, client->name) == 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           call_lost_handler (client); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   else if (g_strcmp0 (signal_name, "NameAcquired") == 0) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-05-13 19:20:26 +02:00
										 |  |  |  |       g_variant_get (parameters, "(&s)", &name); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       if (g_strcmp0 (name, client->name) == 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           call_acquired_handler (client); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |  out: | 
					
						
							|  |  |  |  |   ; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* ---------------------------------------------------------------------------------------------------- */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | request_name_cb (GObject      *source_object, | 
					
						
							|  |  |  |  |                  GAsyncResult *res, | 
					
						
							|  |  |  |  |                  gpointer      user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client = user_data; | 
					
						
							|  |  |  |  |   GVariant *result; | 
					
						
							|  |  |  |  |   guint32 request_name_reply; | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |   gboolean unsubscribe; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   request_name_reply = 0; | 
					
						
							|  |  |  |  |   result = NULL; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |   /* don't use client->connection - it may be NULL already */ | 
					
						
							|  |  |  |  |   result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), | 
					
						
							| 
									
										
										
										
											2010-05-10 11:47:08 -04:00
										 |  |  |  |                                           res, | 
					
						
							|  |  |  |  |                                           NULL); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   if (result != NULL) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       g_variant_get (result, "(u)", &request_name_reply); | 
					
						
							|  |  |  |  |       g_variant_unref (result); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |   unsubscribe = FALSE; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   switch (request_name_reply) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-05-13 12:55:04 +01:00
										 |  |  |  |     case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       /* We got the name - now listen for NameLost and NameAcquired */ | 
					
						
							|  |  |  |  |       call_acquired_handler (client); | 
					
						
							|  |  |  |  |       break; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-13 12:55:04 +01:00
										 |  |  |  |     case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       /* Waiting in line - listen for NameLost and NameAcquired */ | 
					
						
							|  |  |  |  |       call_lost_handler (client); | 
					
						
							|  |  |  |  |       break; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     default: | 
					
						
							|  |  |  |  |       /* assume we couldn't get the name - explicit fallthrough */ | 
					
						
							| 
									
										
										
										
											2024-05-13 12:55:04 +01:00
										 |  |  |  |     case DBUS_REQUEST_NAME_REPLY_EXISTS: | 
					
						
							|  |  |  |  |     case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       /* Some other part of the process is already owning the name */ | 
					
						
							|  |  |  |  |       call_lost_handler (client); | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |       unsubscribe = TRUE; | 
					
						
							|  |  |  |  |       client->needs_release = FALSE; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       break; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |   /* If we’re not the owner and not in the queue, there’s no point in continuing
 | 
					
						
							|  |  |  |  |    * to listen to NameAcquired or NameLost. */ | 
					
						
							|  |  |  |  |   if (unsubscribe) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |       GDBusConnection *connection = NULL; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |       /* make sure we use a known good Connection object since it may be set to
 | 
					
						
							|  |  |  |  |        * NULL at any point after being cancelled | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |        */ | 
					
						
							|  |  |  |  |       G_LOCK (lock); | 
					
						
							|  |  |  |  |       if (!client->cancelled) | 
					
						
							|  |  |  |  |         connection = g_object_ref (client->connection); | 
					
						
							|  |  |  |  |       G_UNLOCK (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       if (connection != NULL) | 
					
						
							|  |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |           if (client->name_acquired_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |             g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_acquired_subscription_id)); | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |           if (client->name_lost_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |             g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_lost_subscription_id)); | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |           g_object_unref (connection); | 
					
						
							|  |  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   client_unref (client); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* ---------------------------------------------------------------------------------------------------- */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | on_connection_disconnected (GDBusConnection *connection, | 
					
						
							|  |  |  |  |                             gboolean         remote_peer_vanished, | 
					
						
							|  |  |  |  |                             GError          *error, | 
					
						
							|  |  |  |  |                             gpointer         user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client = user_data; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (client->disconnected_signal_handler_id > 0) | 
					
						
							|  |  |  |  |     g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); | 
					
						
							|  |  |  |  |   if (client->name_acquired_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |     g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_acquired_subscription_id)); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   if (client->name_lost_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |     g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_lost_subscription_id)); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   g_object_unref (client->connection); | 
					
						
							|  |  |  |  |   client->disconnected_signal_handler_id = 0; | 
					
						
							|  |  |  |  |   client->connection = NULL; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   call_lost_handler (client); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* ---------------------------------------------------------------------------------------------------- */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | has_connection (Client *client) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   /* listen for disconnection */ | 
					
						
							|  |  |  |  |   client->disconnected_signal_handler_id = g_signal_connect (client->connection, | 
					
						
							|  |  |  |  |                                                              "closed", | 
					
						
							|  |  |  |  |                                                              G_CALLBACK (on_connection_disconnected), | 
					
						
							|  |  |  |  |                                                              client); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |   /* Start listening to NameLost and NameAcquired messages. We hold
 | 
					
						
							|  |  |  |  |    * references to the Client in the signal closures, since it’s possible | 
					
						
							|  |  |  |  |    * for a signal to be in-flight after unsubscribing the signal handler. | 
					
						
							|  |  |  |  |    * This creates a reference count cycle, but that’s explicitly broken by | 
					
						
							|  |  |  |  |    * disconnecting the signal handlers before calling client_unref() in | 
					
						
							|  |  |  |  |    * g_bus_unown_name(). | 
					
						
							|  |  |  |  |    * | 
					
						
							|  |  |  |  |    * Subscribe to NameLost and NameAcquired before calling RequestName() to | 
					
						
							|  |  |  |  |    * avoid the potential race of losing the name between receiving a reply to | 
					
						
							|  |  |  |  |    * RequestName() and subscribing to NameLost. The #PreviousCall state will | 
					
						
							|  |  |  |  |    * ensure that the user callbacks get called an appropriate number of times. */ | 
					
						
							|  |  |  |  |   client->name_lost_subscription_id = | 
					
						
							|  |  |  |  |     g_dbus_connection_signal_subscribe (client->connection, | 
					
						
							| 
									
										
										
										
											2024-05-13 12:45:29 +01:00
										 |  |  |  |                                         DBUS_SERVICE_DBUS, | 
					
						
							|  |  |  |  |                                         DBUS_INTERFACE_DBUS, | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |                                         "NameLost", | 
					
						
							| 
									
										
										
										
											2024-05-13 12:45:29 +01:00
										 |  |  |  |                                         DBUS_PATH_DBUS, | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |                                         client->name, | 
					
						
							|  |  |  |  |                                         G_DBUS_SIGNAL_FLAGS_NONE, | 
					
						
							|  |  |  |  |                                         on_name_lost_or_acquired, | 
					
						
							|  |  |  |  |                                         client_ref (client), | 
					
						
							|  |  |  |  |                                         (GDestroyNotify) client_unref); | 
					
						
							|  |  |  |  |   client->name_acquired_subscription_id = | 
					
						
							|  |  |  |  |     g_dbus_connection_signal_subscribe (client->connection, | 
					
						
							| 
									
										
										
										
											2024-05-13 12:45:29 +01:00
										 |  |  |  |                                         DBUS_SERVICE_DBUS, | 
					
						
							|  |  |  |  |                                         DBUS_INTERFACE_DBUS, | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |                                         "NameAcquired", | 
					
						
							| 
									
										
										
										
											2024-05-13 12:45:29 +01:00
										 |  |  |  |                                         DBUS_PATH_DBUS, | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |                                         client->name, | 
					
						
							|  |  |  |  |                                         G_DBUS_SIGNAL_FLAGS_NONE, | 
					
						
							|  |  |  |  |                                         on_name_lost_or_acquired, | 
					
						
							|  |  |  |  |                                         client_ref (client), | 
					
						
							|  |  |  |  |                                         (GDestroyNotify) client_unref); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   /* attempt to acquire the name */ | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |   client->needs_release = TRUE; | 
					
						
							| 
									
										
										
										
											2010-05-10 11:47:08 -04:00
										 |  |  |  |   g_dbus_connection_call (client->connection, | 
					
						
							| 
									
										
										
										
											2024-05-13 12:24:16 +01:00
										 |  |  |  |                           DBUS_SERVICE_DBUS, | 
					
						
							|  |  |  |  |                           DBUS_PATH_DBUS, | 
					
						
							|  |  |  |  |                           DBUS_INTERFACE_DBUS, | 
					
						
							| 
									
										
										
										
											2010-05-10 11:47:08 -04:00
										 |  |  |  |                           "RequestName",           /* method name */ | 
					
						
							|  |  |  |  |                           g_variant_new ("(su)", | 
					
						
							|  |  |  |  |                                          client->name, | 
					
						
							|  |  |  |  |                                          client->flags), | 
					
						
							| 
									
										
										
										
											2010-05-24 16:46:24 -04:00
										 |  |  |  |                           G_VARIANT_TYPE ("(u)"), | 
					
						
							| 
									
										
										
										
											2010-05-10 11:47:08 -04:00
										 |  |  |  |                           G_DBUS_CALL_FLAGS_NONE, | 
					
						
							|  |  |  |  |                           -1, | 
					
						
							|  |  |  |  |                           NULL, | 
					
						
							|  |  |  |  |                           (GAsyncReadyCallback) request_name_cb, | 
					
						
							|  |  |  |  |                           client_ref (client)); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | connection_get_cb (GObject      *source_object, | 
					
						
							|  |  |  |  |                    GAsyncResult *res, | 
					
						
							|  |  |  |  |                    gpointer      user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client = user_data; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-27 10:30:58 -04:00
										 |  |  |  |   /* must not do anything if already cancelled */ | 
					
						
							|  |  |  |  |   G_LOCK (lock); | 
					
						
							|  |  |  |  |   if (client->cancelled) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       G_UNLOCK (lock); | 
					
						
							|  |  |  |  |       goto out; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   G_UNLOCK (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |   client->connection = g_bus_get_finish (res, NULL); | 
					
						
							|  |  |  |  |   if (client->connection == NULL) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       call_lost_handler (client); | 
					
						
							|  |  |  |  |       goto out; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* No need to schedule this in idle as we're already in the thread
 | 
					
						
							|  |  |  |  |    * that the user called g_bus_own_name() from. This is because | 
					
						
							|  |  |  |  |    * g_bus_get() guarantees that. | 
					
						
							|  |  |  |  |    * | 
					
						
							|  |  |  |  |    * Also, we need to ensure that the handler is invoked *before* | 
					
						
							|  |  |  |  |    * we call RequestName(). Otherwise there is a race. | 
					
						
							|  |  |  |  |    */ | 
					
						
							|  |  |  |  |   if (client->bus_acquired_handler != NULL) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       client->bus_acquired_handler (client->connection, | 
					
						
							|  |  |  |  |                                     client->name, | 
					
						
							|  |  |  |  |                                     client->user_data); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   has_connection (client); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |  out: | 
					
						
							|  |  |  |  |   client_unref (client); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* ---------------------------------------------------------------------------------------------------- */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_bus_own_name_on_connection: | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @connection: a bus connection | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * @name: the well-known name to own | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @flags: a set of flags with ownership options | 
					
						
							| 
									
										
										
										
											2023-11-29 11:55:49 +00:00
										 |  |  |  |  * @name_acquired_handler: (nullable) (scope notified): handler to invoke when | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   @name is acquired, or `NULL` to ignore | 
					
						
							| 
									
										
										
										
											2023-11-29 11:55:49 +00:00
										 |  |  |  |  * @name_lost_handler: (nullable) (scope notified): handler to invoke when @name | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   is lost, or `NULL` to ignore | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * @user_data: user data to pass to handlers | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @user_data_free_func: (nullable): function for freeing @user_data | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * Like [func@Gio.bus_own_name] but takes a [class@Gio.DBusConnection] instead | 
					
						
							|  |  |  |  |  * of a [enum@Gio.BusType]. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-08-23 21:45:16 +00:00
										 |  |  |  |  * Returns: an identifier (never 0) that can be used with | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   [func@Gio.bus_unown_name] to stop owning the name | 
					
						
							| 
									
										
										
										
											2010-05-06 16:02:08 -04:00
										 |  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | guint | 
					
						
							|  |  |  |  | g_bus_own_name_on_connection (GDBusConnection          *connection, | 
					
						
							|  |  |  |  |                               const gchar              *name, | 
					
						
							|  |  |  |  |                               GBusNameOwnerFlags        flags, | 
					
						
							|  |  |  |  |                               GBusNameAcquiredCallback  name_acquired_handler, | 
					
						
							|  |  |  |  |                               GBusNameLostCallback      name_lost_handler, | 
					
						
							|  |  |  |  |                               gpointer                  user_data, | 
					
						
							|  |  |  |  |                               GDestroyNotify            user_data_free_func) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0); | 
					
						
							|  |  |  |  |   g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   G_LOCK (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   client = g_new0 (Client, 1); | 
					
						
							|  |  |  |  |   client->ref_count = 1; | 
					
						
							|  |  |  |  |   client->id = next_global_id++; /* TODO: uh oh, handle overflow */ | 
					
						
							|  |  |  |  |   client->name = g_strdup (name); | 
					
						
							|  |  |  |  |   client->flags = flags; | 
					
						
							|  |  |  |  |   client->name_acquired_handler = name_acquired_handler; | 
					
						
							|  |  |  |  |   client->name_lost_handler = name_lost_handler; | 
					
						
							|  |  |  |  |   client->user_data = user_data; | 
					
						
							|  |  |  |  |   client->user_data_free_func = user_data_free_func; | 
					
						
							| 
									
										
										
										
											2011-10-05 10:46:57 -04:00
										 |  |  |  |   client->main_context = g_main_context_ref_thread_default (); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   client->connection = g_object_ref (connection); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (map_id_to_client == NULL) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   g_hash_table_insert (map_id_to_client, | 
					
						
							|  |  |  |  |                        GUINT_TO_POINTER (client->id), | 
					
						
							|  |  |  |  |                        client); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   G_UNLOCK (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   has_connection (client); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return client->id; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_bus_own_name: | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * @bus_type: the type of bus to own a name on | 
					
						
							|  |  |  |  |  * @name: the well-known name to own | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @flags: a set of flags with ownership options | 
					
						
							| 
									
										
										
										
											2023-11-29 11:55:49 +00:00
										 |  |  |  |  * @bus_acquired_handler: (nullable) (scope notified): handler to invoke when | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   connected to the bus of type @bus_type, or `NULL` to ignore | 
					
						
							| 
									
										
										
										
											2023-11-29 11:55:49 +00:00
										 |  |  |  |  * @name_acquired_handler: (nullable) (scope notified): handler to invoke when | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   @name is acquired, or `NULL` to ignore | 
					
						
							| 
									
										
										
										
											2023-11-29 11:55:49 +00:00
										 |  |  |  |  * @name_lost_handler: (nullable) (scope notified): handler to invoke when @name | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   is lost, or `NULL` to ignore | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * @user_data: user data to pass to handlers | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @user_data_free_func: (nullable): function for freeing @user_data | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * Requests ownership of @name on the bus specified by @bus_type. | 
					
						
							|  |  |  |  |  * | 
					
						
							|  |  |  |  |  * It asynchronously calls @name_acquired_handler and @name_lost_handler when | 
					
						
							|  |  |  |  |  * the name is acquired and lost, respectively. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * Callbacks will be invoked in the thread-default | 
					
						
							| 
									
										
										
										
											2025-01-28 21:05:26 +02:00
										 |  |  |  |  * main context (see [method@GLib.MainContext.push_thread_default]) | 
					
						
							| 
									
										
										
										
											2014-02-08 12:26:56 -05:00
										 |  |  |  |  * of the thread you are calling this function from. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * You are guaranteed that one of the @name_acquired_handler and @name_lost_handler | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * callbacks will be invoked after calling this function — there are three | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * possible cases: | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  *  | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * - @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). | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * - @bus_acquired_handler then @name_acquired_handler (if the name was | 
					
						
							|  |  |  |  |  *   obtained). | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * When you are done owning the name, call [func@Gio.bus_unown_name] with the | 
					
						
							|  |  |  |  |  * owner ID this function returns. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * If the name is acquired or lost (for example another application | 
					
						
							|  |  |  |  |  * could acquire the name if you allow replacement or the application | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * currently owning the name exits), the handlers are also invoked. | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * If the [class@Gio.DBusConnection] that is used for attempting to own the name | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * closes, then @name_lost_handler is invoked since it is no longer | 
					
						
							|  |  |  |  |  * possible for other processes to access the process. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * You cannot use [func@Gio.bus_own_name] several times for the same name (unless | 
					
						
							|  |  |  |  |  * interleaved with calls to [func@Gio.bus_unown_name]) — only the first call | 
					
						
							| 
									
										
										
										
											2010-05-09 01:44:11 -04:00
										 |  |  |  |  * will work. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Another guarantee is that invocations of @name_acquired_handler | 
					
						
							|  |  |  |  |  * and @name_lost_handler are guaranteed to alternate; that | 
					
						
							|  |  |  |  |  * is, if @name_acquired_handler is invoked then you are | 
					
						
							|  |  |  |  |  * guaranteed that the next time one of the handlers is invoked, it | 
					
						
							|  |  |  |  |  * will be @name_lost_handler. The reverse is also true. | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * If you plan on exporting objects (using, for example, | 
					
						
							|  |  |  |  |  * [method@Gio.DBusConnection.register_object]), note that it is generally too late | 
					
						
							| 
									
										
										
										
											2010-05-09 01:44:11 -04:00
										 |  |  |  |  * to export the objects in @name_acquired_handler. Instead, you can do this | 
					
						
							|  |  |  |  |  * in @bus_acquired_handler since you are guaranteed that this will run | 
					
						
							|  |  |  |  |  * before @name is requested from the bus. | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * This behavior makes it very simple to write applications that want | 
					
						
							| 
									
										
										
										
											2025-01-28 21:05:26 +02:00
										 |  |  |  |  * to [own names](dbus-name-owning.html#d-bus-name-owning) and export objects. | 
					
						
							| 
									
										
										
										
											2010-05-09 01:44:11 -04:00
										 |  |  |  |  * Simply register objects to be exported in @bus_acquired_handler and | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * unregister the objects (if any) in @name_lost_handler. | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-08-23 21:45:16 +00:00
										 |  |  |  |  * Returns: an identifier (never 0) that can be used with | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   [func@Gio.bus_unown_name] to stop owning the name | 
					
						
							| 
									
										
										
										
											2010-05-06 16:02:08 -04:00
										 |  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | guint | 
					
						
							|  |  |  |  | g_bus_own_name (GBusType                  bus_type, | 
					
						
							|  |  |  |  |                 const gchar              *name, | 
					
						
							|  |  |  |  |                 GBusNameOwnerFlags        flags, | 
					
						
							|  |  |  |  |                 GBusAcquiredCallback      bus_acquired_handler, | 
					
						
							|  |  |  |  |                 GBusNameAcquiredCallback  name_acquired_handler, | 
					
						
							|  |  |  |  |                 GBusNameLostCallback      name_lost_handler, | 
					
						
							|  |  |  |  |                 gpointer                  user_data, | 
					
						
							|  |  |  |  |                 GDestroyNotify            user_data_free_func) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_return_val_if_fail (g_dbus_is_name (name) && !g_dbus_is_unique_name (name), 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   G_LOCK (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   client = g_new0 (Client, 1); | 
					
						
							|  |  |  |  |   client->ref_count = 1; | 
					
						
							|  |  |  |  |   client->id = next_global_id++; /* TODO: uh oh, handle overflow */ | 
					
						
							|  |  |  |  |   client->name = g_strdup (name); | 
					
						
							|  |  |  |  |   client->flags = flags; | 
					
						
							|  |  |  |  |   client->bus_acquired_handler = bus_acquired_handler; | 
					
						
							|  |  |  |  |   client->name_acquired_handler = name_acquired_handler; | 
					
						
							|  |  |  |  |   client->name_lost_handler = name_lost_handler; | 
					
						
							|  |  |  |  |   client->user_data = user_data; | 
					
						
							|  |  |  |  |   client->user_data_free_func = user_data_free_func; | 
					
						
							| 
									
										
										
										
											2011-10-05 10:46:57 -04:00
										 |  |  |  |   client->main_context = g_main_context_ref_thread_default (); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (map_id_to_client == NULL) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       map_id_to_client = g_hash_table_new (g_direct_hash, g_direct_equal); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   g_hash_table_insert (map_id_to_client, | 
					
						
							|  |  |  |  |                        GUINT_TO_POINTER (client->id), | 
					
						
							|  |  |  |  |                        client); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_bus_get (bus_type, | 
					
						
							|  |  |  |  |              NULL, | 
					
						
							|  |  |  |  |              connection_get_cb, | 
					
						
							|  |  |  |  |              client_ref (client)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   G_UNLOCK (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return client->id; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | typedef struct { | 
					
						
							|  |  |  |  |   GClosure *bus_acquired_closure; | 
					
						
							|  |  |  |  |   GClosure *name_acquired_closure; | 
					
						
							|  |  |  |  |   GClosure *name_lost_closure; | 
					
						
							|  |  |  |  | } OwnNameData; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  | 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)) | 
					
						
							| 
									
										
										
										
											2011-06-20 09:06:07 -04:00
										 |  |  |  |         g_closure_set_marshal (bus_acquired_closure, g_cclosure_marshal_generic); | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   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)) | 
					
						
							| 
									
										
										
										
											2011-06-20 09:06:07 -04:00
										 |  |  |  |         g_closure_set_marshal (name_acquired_closure, g_cclosure_marshal_generic); | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   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)) | 
					
						
							| 
									
										
										
										
											2011-06-20 09:06:07 -04:00
										 |  |  |  |         g_closure_set_marshal (name_lost_closure, g_cclosure_marshal_generic); | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   return data; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | static void | 
					
						
							|  |  |  |  | own_with_closures_on_bus_acquired (GDBusConnection *connection, | 
					
						
							|  |  |  |  |                                    const gchar     *name, | 
					
						
							|  |  |  |  |                                    gpointer         user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   OwnNameData *data = user_data; | 
					
						
							| 
									
										
										
										
											2011-09-30 17:08:15 +01:00
										 |  |  |  |   GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); | 
					
						
							|  |  |  |  |   g_value_set_object (¶ms[0], connection); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_init (¶ms[1], G_TYPE_STRING); | 
					
						
							|  |  |  |  |   g_value_set_string (¶ms[1], name); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_closure_invoke (data->bus_acquired_closure, NULL, 2, params, NULL); | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_unset (params + 0); | 
					
						
							|  |  |  |  |   g_value_unset (params + 1); | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | own_with_closures_on_name_acquired (GDBusConnection *connection, | 
					
						
							|  |  |  |  |                                     const gchar     *name, | 
					
						
							|  |  |  |  |                                     gpointer         user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   OwnNameData *data = user_data; | 
					
						
							| 
									
										
										
										
											2011-09-30 17:08:15 +01:00
										 |  |  |  |   GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); | 
					
						
							|  |  |  |  |   g_value_set_object (¶ms[0], connection); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_init (¶ms[1], G_TYPE_STRING); | 
					
						
							|  |  |  |  |   g_value_set_string (¶ms[1], name); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_closure_invoke (data->name_acquired_closure, NULL, 2, params, NULL); | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_unset (params + 0); | 
					
						
							|  |  |  |  |   g_value_unset (params + 1); | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | own_with_closures_on_name_lost (GDBusConnection *connection, | 
					
						
							|  |  |  |  |                                 const gchar     *name, | 
					
						
							|  |  |  |  |                                 gpointer         user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   OwnNameData *data = user_data; | 
					
						
							| 
									
										
										
										
											2011-09-30 17:08:15 +01:00
										 |  |  |  |   GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_init (¶ms[0], G_TYPE_DBUS_CONNECTION); | 
					
						
							|  |  |  |  |   g_value_set_object (¶ms[0], connection); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_init (¶ms[1], G_TYPE_STRING); | 
					
						
							|  |  |  |  |   g_value_set_string (¶ms[1], name); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_closure_invoke (data->name_lost_closure, NULL, 2, params, NULL); | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_value_unset (params + 0); | 
					
						
							|  |  |  |  |   g_value_unset (params + 1); | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | static void | 
					
						
							|  |  |  |  | bus_own_name_free_func (gpointer user_data) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   OwnNameData *data = user_data; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (data->bus_acquired_closure != NULL) | 
					
						
							|  |  |  |  |     g_closure_unref (data->bus_acquired_closure); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (data->name_acquired_closure != NULL) | 
					
						
							|  |  |  |  |     g_closure_unref (data->name_acquired_closure); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (data->name_lost_closure != NULL) | 
					
						
							|  |  |  |  |     g_closure_unref (data->name_lost_closure); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_free (data); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2015-03-12 16:53:18 -04:00
										 |  |  |  |  * g_bus_own_name_with_closures: (rename-to g_bus_own_name) | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * @bus_type: the type of bus to own a name on | 
					
						
							|  |  |  |  |  * @name: the well-known name to own | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @flags: a set of flags with ownership options | 
					
						
							|  |  |  |  |  * @bus_acquired_closure: (nullable): closure to invoke when connected to | 
					
						
							|  |  |  |  |  *   the bus of type @bus_type, or `NULL` to ignore | 
					
						
							|  |  |  |  |  * @name_acquired_closure: (nullable): closure to invoke when @name is | 
					
						
							|  |  |  |  |  *   acquired, or `NULL` to ignore | 
					
						
							|  |  |  |  |  * @name_lost_closure: (nullable): closure to invoke when @name is lost, or | 
					
						
							|  |  |  |  |  *   `NULL` to ignore | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * Version of [func@Gio.bus_own_name using closures instead of callbacks for | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |  * easier binding in other languages. | 
					
						
							|  |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-08-23 21:45:16 +00:00
										 |  |  |  |  * Returns: an identifier (never 0) that can be used with | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   [func@Gio.bus_unown_name] to stop owning the name. | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | guint | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  | 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) | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |   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, | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  |           own_name_data_new (bus_acquired_closure, | 
					
						
							|  |  |  |  |                              name_acquired_closure, | 
					
						
							|  |  |  |  |                              name_lost_closure), | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |           bus_own_name_free_func); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2015-03-12 16:53:18 -04:00
										 |  |  |  |  * g_bus_own_name_on_connection_with_closures: (rename-to g_bus_own_name_on_connection) | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @connection: a bus connection | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * @name: the well-known name to own | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @flags: a set of flags with ownership options | 
					
						
							|  |  |  |  |  * @name_acquired_closure: (nullable): closure to invoke when @name is | 
					
						
							|  |  |  |  |  *   acquired, or `NULL` to ignore | 
					
						
							|  |  |  |  |  * @name_lost_closure: (nullable): closure to invoke when @name is lost, | 
					
						
							|  |  |  |  |  *   or `NULL` to ignore | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * Version of [func@Gio.bus_own_name_on_connection] using closures instead of | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  |  * callbacks for easier binding in other languages. | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-08-23 21:45:16 +00:00
										 |  |  |  |  * Returns: an identifier (never 0) that can be used with | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  *   [func@Gio.bus_unown_name] to stop owning the name. | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |  * Since: 2.26 | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | guint | 
					
						
							| 
									
										
										
										
											2014-01-31 23:47:42 -05:00
										 |  |  |  | g_bus_own_name_on_connection_with_closures (GDBusConnection    *connection, | 
					
						
							|  |  |  |  |                                             const gchar        *name, | 
					
						
							|  |  |  |  |                                             GBusNameOwnerFlags  flags, | 
					
						
							|  |  |  |  |                                             GClosure           *name_acquired_closure, | 
					
						
							|  |  |  |  |                                             GClosure           *name_lost_closure) | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  | { | 
					
						
							|  |  |  |  |   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, | 
					
						
							| 
									
										
										
										
											2010-08-07 16:27:38 -04:00
										 |  |  |  |           own_name_data_new (NULL, | 
					
						
							|  |  |  |  |                              name_acquired_closure, | 
					
						
							|  |  |  |  |                              name_lost_closure), | 
					
						
							| 
									
										
										
										
											2010-06-10 18:29:23 +02:00
										 |  |  |  |           bus_own_name_free_func); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  | /**
 | 
					
						
							|  |  |  |  |  * g_bus_unown_name: | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * @owner_id: an identifier obtained from [func@Gio.bus_own_name] | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  * | 
					
						
							|  |  |  |  |  * Stops owning a name. | 
					
						
							| 
									
										
										
										
											2010-05-06 16:02:08 -04:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2020-02-21 15:12:08 +00:00
										 |  |  |  |  * Note that there may still be D-Bus traffic to process (relating to owning | 
					
						
							| 
									
										
										
										
											2025-03-19 20:38:38 +00:00
										 |  |  |  |  * and unowning the name) in the current thread-default | 
					
						
							|  |  |  |  |  * [struct@GLib.MainContext] after this function has returned. You should | 
					
						
							|  |  |  |  |  * continue to iterate the [struct@GLib.MainContext] until the | 
					
						
							|  |  |  |  |  * [callback@GLib.DestroyNotify] function passed to [func@Gio.bus_own_name] is | 
					
						
							|  |  |  |  |  * called, in order to avoid memory leaks through callbacks queued on the | 
					
						
							|  |  |  |  |  * [struct@GLib.MainContext] after it’s stopped being iterated. | 
					
						
							| 
									
										
										
										
											2020-02-21 15:12:08 +00:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-05-06 16:02:08 -04:00
										 |  |  |  |  * Since: 2.26 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |  */ | 
					
						
							|  |  |  |  | void | 
					
						
							|  |  |  |  | g_bus_unown_name (guint owner_id) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   Client *client; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   g_return_if_fail (owner_id > 0); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   client = NULL; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   G_LOCK (lock); | 
					
						
							|  |  |  |  |   if (owner_id == 0 || map_id_to_client == NULL || | 
					
						
							|  |  |  |  |       (client = g_hash_table_lookup (map_id_to_client, GUINT_TO_POINTER (owner_id))) == NULL) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       g_warning ("Invalid id %d passed to g_bus_unown_name()", owner_id); | 
					
						
							|  |  |  |  |       goto out; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   client->cancelled = TRUE; | 
					
						
							|  |  |  |  |   g_warn_if_fail (g_hash_table_remove (map_id_to_client, GUINT_TO_POINTER (owner_id))); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |  out: | 
					
						
							|  |  |  |  |   G_UNLOCK (lock); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* do callback without holding lock */ | 
					
						
							|  |  |  |  |   if (client != NULL) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |       /* Release the name if needed */ | 
					
						
							| 
									
										
										
										
											2013-07-19 11:50:35 -04:00
										 |  |  |  |       if (client->needs_release && | 
					
						
							|  |  |  |  |           client->connection != NULL && | 
					
						
							|  |  |  |  |           !g_dbus_connection_is_closed (client->connection)) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |         { | 
					
						
							|  |  |  |  |           GVariant *result; | 
					
						
							|  |  |  |  |           GError *error; | 
					
						
							|  |  |  |  |           guint32 release_name_reply; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           /* TODO: it kinda sucks having to do a sync call to release the name - but if
 | 
					
						
							|  |  |  |  |            * we don't, then a subsequent grab of the name will make the bus daemon return | 
					
						
							|  |  |  |  |            * IN_QUEUE which will trigger name_lost(). | 
					
						
							|  |  |  |  |            * | 
					
						
							|  |  |  |  |            * I believe this is a bug in the bus daemon. | 
					
						
							|  |  |  |  |            */ | 
					
						
							|  |  |  |  |           error = NULL; | 
					
						
							| 
									
										
										
										
											2010-05-10 11:47:08 -04:00
										 |  |  |  |           result = g_dbus_connection_call_sync (client->connection, | 
					
						
							| 
									
										
										
										
											2024-05-13 12:24:16 +01:00
										 |  |  |  |                                                 DBUS_SERVICE_DBUS, | 
					
						
							|  |  |  |  |                                                 DBUS_PATH_DBUS, | 
					
						
							|  |  |  |  |                                                 DBUS_INTERFACE_DBUS, | 
					
						
							| 
									
										
										
										
											2010-05-10 11:47:08 -04:00
										 |  |  |  |                                                 "ReleaseName",           /* method name */ | 
					
						
							|  |  |  |  |                                                 g_variant_new ("(s)", client->name), | 
					
						
							| 
									
										
										
										
											2010-05-24 16:46:24 -04:00
										 |  |  |  |                                                 G_VARIANT_TYPE ("(u)"), | 
					
						
							| 
									
										
										
										
											2010-05-10 11:47:08 -04:00
										 |  |  |  |                                                 G_DBUS_CALL_FLAGS_NONE, | 
					
						
							|  |  |  |  |                                                 -1, | 
					
						
							|  |  |  |  |                                                 NULL, | 
					
						
							|  |  |  |  |                                                 &error); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |           if (result == NULL) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |               g_warning ("Error releasing name %s: %s", client->name, error->message); | 
					
						
							|  |  |  |  |               g_error_free (error); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |           else | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |               g_variant_get (result, "(u)", &release_name_reply); | 
					
						
							| 
									
										
										
										
											2024-05-13 12:55:04 +01:00
										 |  |  |  |               if (release_name_reply != DBUS_RELEASE_NAME_REPLY_RELEASED) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |                 { | 
					
						
							|  |  |  |  |                   g_warning ("Unexpected reply %d when releasing name %s", release_name_reply, client->name); | 
					
						
							|  |  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2020-02-16 09:57:30 +00:00
										 |  |  |  |               else | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                   client->needs_release = FALSE; | 
					
						
							|  |  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |               g_variant_unref (result); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       if (client->disconnected_signal_handler_id > 0) | 
					
						
							|  |  |  |  |         g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); | 
					
						
							|  |  |  |  |       if (client->name_acquired_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |         g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_acquired_subscription_id)); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       if (client->name_lost_subscription_id > 0) | 
					
						
							| 
									
										
										
										
											2024-10-08 13:55:22 +01:00
										 |  |  |  |         g_dbus_connection_signal_unsubscribe (client->connection, g_steal_handle_id (&client->name_lost_subscription_id)); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:13:59 -04:00
										 |  |  |  |       client->disconnected_signal_handler_id = 0; | 
					
						
							|  |  |  |  |       if (client->connection != NULL) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |           g_object_unref (client->connection); | 
					
						
							|  |  |  |  |           client->connection = NULL; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       client_unref (client); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } |