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
|
||||||
secret_service_get_sync
|
secret_service_get_sync
|
||||||
secret_service_get_finish
|
secret_service_get_finish
|
||||||
|
secret_service_disconnect
|
||||||
secret_service_new
|
secret_service_new
|
||||||
secret_service_new_finish
|
secret_service_new_finish
|
||||||
secret_service_new_sync
|
secret_service_new_sync
|
||||||
|
@ -124,6 +124,7 @@ struct _SecretServicePrivate {
|
|||||||
|
|
||||||
G_LOCK_DEFINE (service_instance);
|
G_LOCK_DEFINE (service_instance);
|
||||||
static gpointer service_instance = NULL;
|
static gpointer service_instance = NULL;
|
||||||
|
static guint service_watch = 0;
|
||||||
|
|
||||||
static GInitableIface *secret_service_initable_parent_iface = NULL;
|
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);
|
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
|
static void
|
||||||
secret_service_init (SecretService *self)
|
secret_service_init (SecretService *self)
|
||||||
{
|
{
|
||||||
@ -678,10 +757,7 @@ secret_service_get (SecretServiceFlags flags,
|
|||||||
GSimpleAsyncResult *res;
|
GSimpleAsyncResult *res;
|
||||||
InitClosure *closure;
|
InitClosure *closure;
|
||||||
|
|
||||||
G_LOCK (service_instance);
|
service = service_get_instance ();
|
||||||
if (service_instance != NULL)
|
|
||||||
service = g_object_ref (service_instance);
|
|
||||||
G_UNLOCK (service_instance);
|
|
||||||
|
|
||||||
/* Create a whole new service */
|
/* Create a whole new service */
|
||||||
if (service == NULL) {
|
if (service == NULL) {
|
||||||
@ -743,13 +819,8 @@ secret_service_get_finish (GAsyncResult *result,
|
|||||||
/* Creating a whole new service */
|
/* Creating a whole new service */
|
||||||
} else {
|
} else {
|
||||||
service = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
|
service = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
|
||||||
|
if (service)
|
||||||
if (service) {
|
service_cache_instance (SECRET_SERVICE (service));
|
||||||
G_LOCK (service_instance);
|
|
||||||
if (service_instance == NULL)
|
|
||||||
service_instance = g_object_ref (service);
|
|
||||||
G_UNLOCK (service_instance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source_object)
|
if (source_object)
|
||||||
@ -786,10 +857,7 @@ secret_service_get_sync (SecretServiceFlags flags,
|
|||||||
{
|
{
|
||||||
SecretService *service = NULL;
|
SecretService *service = NULL;
|
||||||
|
|
||||||
G_LOCK (service_instance);
|
service = service_get_instance ();
|
||||||
if (service_instance != NULL)
|
|
||||||
service = g_object_ref (service_instance);
|
|
||||||
G_UNLOCK (service_instance);
|
|
||||||
|
|
||||||
if (service == NULL) {
|
if (service == NULL) {
|
||||||
service = g_initable_new (SECRET_TYPE_SERVICE, cancellable, error,
|
service = g_initable_new (SECRET_TYPE_SERVICE, cancellable, error,
|
||||||
@ -802,12 +870,8 @@ secret_service_get_sync (SecretServiceFlags flags,
|
|||||||
"flags", flags,
|
"flags", flags,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (service != NULL) {
|
if (service != NULL)
|
||||||
G_LOCK (service_instance);
|
service_cache_instance (service);
|
||||||
if (service_instance == NULL)
|
|
||||||
service_instance = g_object_ref (service);
|
|
||||||
G_UNLOCK (service_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!service_ensure_for_flags_sync (service, flags, cancellable, error)) {
|
if (!service_ensure_for_flags_sync (service, flags, cancellable, error)) {
|
||||||
@ -835,15 +899,7 @@ secret_service_get_sync (SecretServiceFlags flags,
|
|||||||
void
|
void
|
||||||
secret_service_disconnect (void)
|
secret_service_disconnect (void)
|
||||||
{
|
{
|
||||||
SecretService *instance;
|
service_uncache_instance (NULL);
|
||||||
|
|
||||||
G_LOCK (service_instance);
|
|
||||||
instance = service_instance;
|
|
||||||
service_instance = NULL;
|
|
||||||
G_UNLOCK (service_instance);
|
|
||||||
|
|
||||||
if (instance != NULL)
|
|
||||||
g_object_unref (instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,5 +88,6 @@ mock_service_stop (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_spawn_close_pid (pid);
|
g_spawn_close_pid (pid);
|
||||||
|
secret_service_disconnect ();
|
||||||
pid = 0;
|
pid = 0;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,6 @@ static void
|
|||||||
teardown (Test *test,
|
teardown (Test *test,
|
||||||
gconstpointer unused)
|
gconstpointer unused)
|
||||||
{
|
{
|
||||||
secret_service_disconnect ();
|
|
||||||
mock_service_stop ();
|
mock_service_stop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user