summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2022-10-27 09:18:53 -0400
committerMichael Catanzaro <mcatanzaro@gnome.org>2023-01-20 14:49:40 -0500
commit0e9c32dda302a9c8299996057563bca25bc1d36c (patch)
tree3211777ac805aa8e34ee33b046559123a6f6aef0
parentc8c1ccea8fc1224afcf1c3a2994aa169615531fb (diff)
downloadgnome-online-accounts-0e9c32dda302a9c8299996057563bca25bc1d36c.tar.gz
kerberos-identity: Ensure idles queued to main thread are property synchronized
Kerberos identities are refreshed on a helper thread, and the state of those identities are exported over the user bus on the main thread. Since the main consumer of an identity's properties is the bus service running on the main thread, to simplify things, property notifications are dispatched from the main thread as well (even though the underlying state is changed on a worker thread). The mechanism to dispatch property notifies to the main thread is an idle handler. The logic for doing the dispatch has a concurrency bug however. In order to coaelsce multiple notifies that happen in quick succession, the dispatch code checks for a preexisting idle id associated with the given property. That idle id is set from the worker thread when the idle is queued, and it's cleared from the main thread when the idle is dispatched. The bug is that the main thread could in theory clear the idle id immediately after the worker thread decided there was already a notify queued, leading to a notify getting completely dropped. This commit addresses the bug by adding appropriate locking. Closes https://gitlab.gnome.org/GNOME/gnome-online-accounts/-/issues/160 (cherry picked from commit 709e1db83ebf8980f4367d548f12d25a69e77955)
-rw-r--r--src/goaidentity/goakerberosidentity.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c
index d5eaeed..6994ad6 100644
--- a/src/goaidentity/goakerberosidentity.c
+++ b/src/goaidentity/goakerberosidentity.c
@@ -520,7 +520,10 @@ typedef struct
static void
clear_idle_id (NotifyRequest *request)
{
+ G_LOCK (identity_lock);
*request->idle_id = 0;
+ G_UNLOCK (identity_lock);
+
g_object_unref (request->self);
g_slice_free (NotifyRequest, request);
}