diff options
author | Stefan Walter <stefw@src.gnome.org> | 2008-01-15 05:00:16 +0000 |
---|---|---|
committer | Stefan Walter <stefw@src.gnome.org> | 2008-01-15 05:00:16 +0000 |
commit | 0e616ac7e9cd67834218ae2d6ef2dd37a8ea5e4a (patch) | |
tree | ad6eeb51623b67660b9f1eae2d9a558a96af5291 /common | |
parent | d24ce5a48dd3b5546e5f6c291ba4017b2e68300f (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.c | 16 |
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); |