From 1d945f638033e7649ea61fa1c4050b30da891d6b Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Fri, 18 Dec 2015 02:29:48 -0500 Subject: [PATCH] PRELIMINARY: Fix bug in fat_mutex_unlock. --- libguile/threads.c | 87 ++++++++++++++++++++++-------------------------------- 1 file changed, 36 insertions(+), 51 deletions(-) diff --git a/libguile/threads.c b/libguile/threads.c index 6ae6818..dcbd24d 100644 --- a/libguile/threads.c +++ b/libguile/threads.c @@ -1607,70 +1607,55 @@ fat_mutex_unlock (SCM mutex, SCM cond, } } + if (m->level > 0) + m->level--; + if (m->level == 0) + { + /* Change the owner of MUTEX. */ + t->mutexes = scm_delq_x (mutex, t->mutexes); + m->owner = unblock_from_queue (m->waiting); + } + if (! (SCM_UNBNDP (cond))) { c = SCM_CONDVAR_DATA (cond); - while (1) - { - int brk = 0; - - if (m->level > 0) - m->level--; - if (m->level == 0) - { - /* Change the owner of MUTEX. */ - t->mutexes = scm_delq_x (mutex, t->mutexes); - m->owner = unblock_from_queue (m->waiting); - } - - t->block_asyncs++; + t->block_asyncs++; + do + { err = block_self (c->waiting, cond, &m->lock, waittime); scm_i_pthread_mutex_unlock (&m->lock); - if (err == 0) - { - ret = 1; - brk = 1; - } - else if (err == ETIMEDOUT) - { - ret = 0; - brk = 1; - } - else if (err != EINTR) - { - errno = err; - scm_syserror (NULL); - } - - if (brk) - { - if (relock) - scm_lock_mutex_timed (mutex, SCM_UNDEFINED, owner); - t->block_asyncs--; - break; - } - - t->block_asyncs--; - scm_async_click (); + if (err == EINTR) + { + t->block_asyncs--; + scm_async_click (); - scm_remember_upto_here_2 (cond, mutex); + scm_remember_upto_here_2 (cond, mutex); - scm_i_scm_pthread_mutex_lock (&m->lock); + scm_i_scm_pthread_mutex_lock (&m->lock); + t->block_asyncs++; + } } + while (err == EINTR); + + if (err == 0) + ret = 1; + else if (err == ETIMEDOUT) + ret = 0; + else + { + t->block_asyncs--; + errno = err; + scm_syserror (NULL); + } + + if (relock) + scm_lock_mutex_timed (mutex, SCM_UNDEFINED, owner); + t->block_asyncs--; } else { - if (m->level > 0) - m->level--; - if (m->level == 0) - { - /* Change the owner of MUTEX. */ - t->mutexes = scm_delq_x (mutex, t->mutexes); - m->owner = unblock_from_queue (m->waiting); - } - scm_i_pthread_mutex_unlock (&m->lock); ret = 1; } -- 2.6.3