Commit ccbcbb79 authored by Zeeshan Ali's avatar Zeeshan Ali

dbus,manager: Add DeleteClient() method

Add a method for apps to explicitly delete their client objects. This is
useful for long-running applications (e.g gnome-settings-daemon) for
freeing their associated resources while they are not using Geoclue. This
will also allow geoclue to exit when it's not actually being used by these
applications.

Relevant: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/issues/127

Fixes #99.
parent c60f17c2
Pipeline #13818 passed with stage
in 2 minutes and 16 seconds
......@@ -113,30 +113,18 @@ compare_client_bus_name (gconstpointer a,
}
static void
on_peer_vanished (GClueClientInfo *info,
gpointer user_data)
delete_client (GClueServiceManager *manager,
GCompareFunc compare_func,
gpointer compare_func_data)
{
GClueServiceManager *manager = GCLUE_SERVICE_MANAGER (user_data);
GClueServiceManagerPrivate *priv = manager->priv;
GList *l;
const char *bus_name;
bus_name = gclue_client_info_get_bus_name (info);
l = priv->clients;
while (l != NULL) {
GList *next = l->next;
if (compare_client_bus_name (l->data, bus_name) == 0) {
const char *id, *path;
id = gclue_dbus_client_get_desktop_id
(GCLUE_DBUS_CLIENT (l->data));
path = gclue_service_client_get_path
(GCLUE_SERVICE_CLIENT (l->data));
g_debug ("Client `%s` vanished. Dropping associated "
"client object `%s`", id, path);
if (compare_func (l->data, compare_func_data) == 0) {
g_object_unref (G_OBJECT (l->data));
priv->clients = g_list_remove_link (priv->clients, l);
priv->num_clients--;
......@@ -151,6 +139,21 @@ on_peer_vanished (GClueClientInfo *info,
sync_in_use_property (manager);
}
static void
on_peer_vanished (GClueClientInfo *info,
gpointer user_data)
{
const char *bus_name;
bus_name = gclue_client_info_get_bus_name (info);
g_debug ("Client `%s` vanished. Dropping associated client objects",
bus_name);
delete_client (GCLUE_SERVICE_MANAGER (user_data),
compare_client_bus_name,
(char *) bus_name);
}
typedef struct
{
GClueDBusManager *manager;
......@@ -329,6 +332,51 @@ gclue_service_manager_handle_create_client (GClueDBusManager *manager,
return TRUE;
}
typedef struct
{
const char *path;
const char *bus_name;
} CompareClientPathNBusNameData;
static int
compare_client_path_n_bus_name (gconstpointer a,
gconstpointer b)
{
GClueServiceClient *client = GCLUE_SERVICE_CLIENT (a);
CompareClientPathNBusNameData *data =
(CompareClientPathNBusNameData *) b;
GClueClientInfo *info;
info = gclue_service_client_get_client_info (client);
if (g_strcmp0 (data->bus_name,
gclue_client_info_get_bus_name (info)) == 0 &&
g_strcmp0 (data->path,
gclue_service_client_get_path (client)) == 0)
return 0;
else
return 1;
}
static gboolean
gclue_service_manager_handle_delete_client (GClueDBusManager *manager,
GDBusMethodInvocation *invocation,
const char *path)
{
CompareClientPathNBusNameData data;
data.path = path;
data.bus_name = g_dbus_method_invocation_get_sender (invocation);
delete_client (GCLUE_SERVICE_MANAGER (manager),
compare_client_path_n_bus_name,
&data);
gclue_dbus_manager_complete_delete_client (manager, invocation);
return TRUE;
}
typedef struct
{
GClueDBusManager *manager;
......@@ -627,6 +675,8 @@ gclue_service_manager_manager_iface_init (GClueDBusManagerIface *iface)
iface->handle_get_client = gclue_service_manager_handle_get_client;
iface->handle_create_client =
gclue_service_manager_handle_create_client;
iface->handle_delete_client =
gclue_service_manager_handle_delete_client;
iface->handle_add_agent = gclue_service_manager_handle_add_agent;
}
......
......@@ -61,6 +61,23 @@
<arg name="client" type="o" direction="out"/>
</method>
<!--
DeleteClient:
@client: The path of the client object to delete
Use this method to explicitly destroy a client, created using
org.freedesktop.GeoClue2.Manager.GetClient() or
org.freedesktop.GeoClue2.Manager.CreateClient().
Long-running applications, should either use this to delete associated
client(s) when not needed, or disconnect from the D-Bus connection used
for communicating with Geoclue (which is implicit on client process
termination).
-->
<method name="DeleteClient">
<arg name="client" type="o" direction="in"/>
</method>
<!--
AddAgent:
@id: The Desktop ID (excluding .desktop) of the agent
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment