guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 05/07: Prevent some interrupts of wait-condition-variabl


From: Andy Wingo
Subject: [Guile-commits] 05/07: Prevent some interrupts of wait-condition-variable
Date: Sun, 8 Jan 2017 14:51:37 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 12eb7b8256f579fab60ebe0b38eb8788c1276eb8
Author: Andy Wingo <address@hidden>
Date:   Sun Jan 8 13:18:13 2017 +0100

    Prevent some interrupts of wait-condition-variable
    
    * libguile/threads.c (timed_wait): Disable interrupts while reacquiring
      mutex after wait-condition-variable.
---
 libguile/threads.c |   28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/libguile/threads.c b/libguile/threads.c
index 64bef8c..7d91a01 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -1290,7 +1290,23 @@ timed_wait (enum scm_mutex_kind kind, struct scm_mutex 
*m, struct scm_cond *c,
       err = block_self (c->waiting, &m->lock, waittime);
 
       /* We woke up for some reason.  Reacquire the mutex before doing
-         anything else.  */
+         anything else.
+
+         FIXME: We disable interrupts while reacquiring the mutex.  If
+         we allow interrupts here, there's the risk of a nonlocal exit
+         before we reaquire the mutex, which would be visible to user
+         code.
+
+         For example the unwind handler in
+
+           (with-mutex m (wait-condition-variable c m))
+
+         that tries to unlock M could see M in an already-unlocked
+         state, if an interrupt while waiting on C caused the wait to
+         abort and the woke thread lost the race to reacquire M.  That's
+         not great.  Maybe it's necessary but for now we just disable
+         interrupts while reaquiring a mutex after a wait.  */
+      current_thread->block_asyncs++;
       if (kind == SCM_MUTEX_RECURSIVE &&
           scm_is_eq (m->owner, current_thread->handle))
        {
@@ -1307,16 +1323,8 @@ timed_wait (enum scm_mutex_kind kind, struct scm_mutex 
*m, struct scm_cond *c,
                 break;
               }
             block_self (m->waiting, &m->lock, waittime);
-            if (scm_is_eq (m->owner, SCM_BOOL_F))
-              {
-                m->owner = current_thread->handle;
-                scm_i_pthread_mutex_unlock (&m->lock);
-                break;
-              }
-            scm_i_pthread_mutex_unlock (&m->lock);
-            scm_async_tick ();
-            scm_i_scm_pthread_mutex_lock (&m->lock);
           }
+      current_thread->block_asyncs--;
 
       /* Now that we have the mutex again, handle the return value.  */
       if (err == 0)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]