summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorStefan Walter <stefw@src.gnome.org>2008-01-15 05:00:16 +0000
committerStefan Walter <stefw@src.gnome.org>2008-01-15 05:00:16 +0000
commit0e616ac7e9cd67834218ae2d6ef2dd37a8ea5e4a (patch)
treead6eeb51623b67660b9f1eae2d9a558a96af5291 /common
parentd24ce5a48dd3b5546e5f6c291ba4017b2e68300f (diff)
Fix race condition that is causing a deadlock in bug #502603.
* common/gkr-async.c: Fix race condition that is causing a deadlock in bug #502603. svn path=/trunk/; revision=1012
Diffstat (limited to 'common')
-rw-r--r--common/gkr-async.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/common/gkr-async.c b/common/gkr-async.c
index ff29adb3..fcae54c2 100644
--- a/common/gkr-async.c
+++ b/common/gkr-async.c
@@ -34,6 +34,10 @@
#define DEBUG_LOCKS 0
+/*
+ * See comments on async_poll_func() on the order of the various
+ * gets and sets of waiting_on_* flags.
+ */
#if DEBUG_LOCKS
#define DO_LOCK(mtx) G_STMT_START { \
g_printerr ("%s LOCK %s\n", __func__, G_STRINGIFY(mtx)); \
@@ -93,8 +97,18 @@ async_poll_func (GPollFD *ufds, guint nfsd, gint timeout)
gint ret;
g_assert (orig_poll_func);
+
+ /*
+ * These two atomic variables are interlocked in the
+ * opposite order from those in DO_LOCK which prevents
+ * race conditions in the if statements.
+ */
g_atomic_int_set (&waiting_on_poll, 1);
+ if (g_atomic_int_get (&waiting_on_lock))
+ timeout = 0;
+
ret = (orig_poll_func) (ufds, nfsd, timeout);
+
g_atomic_int_set (&waiting_on_poll, 0);
if (done_queue && !g_queue_is_empty (done_queue))
@@ -314,7 +328,6 @@ cleanup_done_thread (gpointer message, gpointer data)
running_workers = NULL;
g_assert (main_loop);
- gkr_wakeup_register (g_main_loop_get_context (main_loop));
return FALSE;
}
@@ -346,7 +359,6 @@ gkr_async_worker_start (GThreadFunc func, GkrAsyncWorkerCallback callback,
if (!done_queue) {
g_assert (main_loop);
- gkr_wakeup_register (g_main_loop_get_context (main_loop));
done_queue = g_queue_new ();
g_assert (!running_workers);