diff options
author | Andy Wingo <wingo@pobox.com> | 2017-01-08 13:18:13 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2017-01-08 13:18:13 +0100 |
commit | 12eb7b8256f579fab60ebe0b38eb8788c1276eb8 (patch) | |
tree | 5c70aee46e8d0201e328744e1fedfb67a81940c9 /libguile/threads.c | |
parent | a000e5c38d50883c517214776dda36f4e478ebad (diff) | |
download | guile-12eb7b8256f579fab60ebe0b38eb8788c1276eb8.tar.gz |
Prevent some interrupts of wait-condition-variable
* libguile/threads.c (timed_wait): Disable interrupts while reacquiring
mutex after wait-condition-variable.
Diffstat (limited to 'libguile/threads.c')
-rw-r--r-- | libguile/threads.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/libguile/threads.c b/libguile/threads.c index 64bef8c89..7d91a01da 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) |