mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-22 12:48:51 +00:00
Disconnect the cached default SecretService if service goes away
* Because the session would no longer be valid if the service was autostarted for the same SecretService proxy
This commit is contained in:
parent
b535ed1bbf
commit
175ae08984
@ -174,6 +174,7 @@ SecretServiceFlags
|
||||
secret_service_get
|
||||
secret_service_get_sync
|
||||
secret_service_get_finish
|
||||
secret_service_disconnect
|
||||
secret_service_new
|
||||
secret_service_new_finish
|
||||
secret_service_new_sync
|
||||
|
@ -124,6 +124,7 @@ struct _SecretServicePrivate {
|
||||
|
||||
G_LOCK_DEFINE (service_instance);
|
||||
static gpointer service_instance = NULL;
|
||||
static guint service_watch = 0;
|
||||
|
||||
static GInitableIface *secret_service_initable_parent_iface = NULL;
|
||||
|
||||
@ -138,6 +139,84 @@ G_DEFINE_TYPE_WITH_CODE (SecretService, secret_service, G_TYPE_DBUS_PROXY,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, secret_service_async_initable_iface);
|
||||
);
|
||||
|
||||
static SecretService *
|
||||
service_get_instance (void)
|
||||
{
|
||||
SecretService *instance = NULL;
|
||||
|
||||
G_LOCK (service_instance);
|
||||
if (service_instance != NULL)
|
||||
instance = g_object_ref (service_instance);
|
||||
G_UNLOCK (service_instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
service_uncache_instance (SecretService *which)
|
||||
{
|
||||
SecretService *instance = NULL;
|
||||
guint watch = 0;
|
||||
gboolean matched = FALSE;
|
||||
|
||||
G_LOCK (service_instance);
|
||||
if (which == NULL || service_instance == which) {
|
||||
instance = service_instance;
|
||||
service_instance = NULL;
|
||||
watch = service_watch;
|
||||
service_watch = 0;
|
||||
matched = TRUE;
|
||||
}
|
||||
G_UNLOCK (service_instance);
|
||||
|
||||
if (instance != NULL)
|
||||
g_object_unref (instance);
|
||||
if (watch != 0)
|
||||
g_bus_unwatch_name (watch);
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
static void
|
||||
on_service_instance_vanished (GDBusConnection *connection,
|
||||
const gchar *name,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (!service_uncache_instance (user_data)) {
|
||||
g_warning ("Global default SecretService instance out of sync "
|
||||
"with the watch for its DBus name");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
service_cache_instance (SecretService *instance)
|
||||
{
|
||||
GDBusProxy *proxy;
|
||||
guint watch;
|
||||
|
||||
g_object_ref (instance);
|
||||
proxy = G_DBUS_PROXY (instance);
|
||||
watch = g_bus_watch_name_on_connection (g_dbus_proxy_get_connection (proxy),
|
||||
g_dbus_proxy_get_name (proxy),
|
||||
G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
|
||||
NULL, on_service_instance_vanished,
|
||||
instance, NULL);
|
||||
|
||||
G_LOCK (service_instance);
|
||||
if (service_instance == NULL) {
|
||||
service_instance = instance;
|
||||
instance = NULL;
|
||||
service_watch = watch;
|
||||
watch = 0;
|
||||
}
|
||||
G_UNLOCK (service_instance);
|
||||
|
||||
if (instance != NULL)
|
||||
g_object_unref (instance);
|
||||
if (watch != 0)
|
||||
g_bus_unwatch_name (watch);
|
||||
}
|
||||
|
||||
static void
|
||||
secret_service_init (SecretService *self)
|
||||
{
|
||||
@ -678,10 +757,7 @@ secret_service_get (SecretServiceFlags flags,
|
||||
GSimpleAsyncResult *res;
|
||||
InitClosure *closure;
|
||||
|
||||
G_LOCK (service_instance);
|
||||
if (service_instance != NULL)
|
||||
service = g_object_ref (service_instance);
|
||||
G_UNLOCK (service_instance);
|
||||
service = service_get_instance ();
|
||||
|
||||
/* Create a whole new service */
|
||||
if (service == NULL) {
|
||||
@ -743,13 +819,8 @@ secret_service_get_finish (GAsyncResult *result,
|
||||
/* Creating a whole new service */
|
||||
} else {
|
||||
service = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
|
||||
|
||||
if (service) {
|
||||
G_LOCK (service_instance);
|
||||
if (service_instance == NULL)
|
||||
service_instance = g_object_ref (service);
|
||||
G_UNLOCK (service_instance);
|
||||
}
|
||||
if (service)
|
||||
service_cache_instance (SECRET_SERVICE (service));
|
||||
}
|
||||
|
||||
if (source_object)
|
||||
@ -786,10 +857,7 @@ secret_service_get_sync (SecretServiceFlags flags,
|
||||
{
|
||||
SecretService *service = NULL;
|
||||
|
||||
G_LOCK (service_instance);
|
||||
if (service_instance != NULL)
|
||||
service = g_object_ref (service_instance);
|
||||
G_UNLOCK (service_instance);
|
||||
service = service_get_instance ();
|
||||
|
||||
if (service == NULL) {
|
||||
service = g_initable_new (SECRET_TYPE_SERVICE, cancellable, error,
|
||||
@ -802,12 +870,8 @@ secret_service_get_sync (SecretServiceFlags flags,
|
||||
"flags", flags,
|
||||
NULL);
|
||||
|
||||
if (service != NULL) {
|
||||
G_LOCK (service_instance);
|
||||
if (service_instance == NULL)
|
||||
service_instance = g_object_ref (service);
|
||||
G_UNLOCK (service_instance);
|
||||
}
|
||||
if (service != NULL)
|
||||
service_cache_instance (service);
|
||||
|
||||
} else {
|
||||
if (!service_ensure_for_flags_sync (service, flags, cancellable, error)) {
|
||||
@ -835,15 +899,7 @@ secret_service_get_sync (SecretServiceFlags flags,
|
||||
void
|
||||
secret_service_disconnect (void)
|
||||
{
|
||||
SecretService *instance;
|
||||
|
||||
G_LOCK (service_instance);
|
||||
instance = service_instance;
|
||||
service_instance = NULL;
|
||||
G_UNLOCK (service_instance);
|
||||
|
||||
if (instance != NULL)
|
||||
g_object_unref (instance);
|
||||
service_uncache_instance (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,5 +88,6 @@ mock_service_stop (void)
|
||||
}
|
||||
|
||||
g_spawn_close_pid (pid);
|
||||
secret_service_disconnect ();
|
||||
pid = 0;
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ static void
|
||||
teardown (Test *test,
|
||||
gconstpointer unused)
|
||||
{
|
||||
secret_service_disconnect ();
|
||||
mock_service_stop ();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user