diff options
| -rw-r--r-- | ChangeLog | 9 | ||||
| -rw-r--r-- | ext/thread/thread.c | 17 |
2 files changed, 15 insertions, 11 deletions
@@ -1,3 +1,12 @@ +Fri Mar 16 16:21:35 2007 Akinori MUSHA <knu@iDaemons.org> + + * ext/thread/thread.c (wait_condvar, lock_mutex): Fix a problem in + ConditionVariable#wait that occurs when two threads that are + trying to access the condition variable are also in concurrence + for the given mutex; submitted by: Sylvain Joyeux + <sylvain.joyeux AT m4x.org> and MenTaLguY <mental AT rydia.net> + in [ruby-core:10598]. + Fri Mar 16 16:17:27 2007 Akinori MUSHA <knu@iDaemons.org> * test/thread/test_thread.rb: Add a test script for the `thread' diff --git a/ext/thread/thread.c b/ext/thread/thread.c index e9dde37a18..54681a8c90 100644 --- a/ext/thread/thread.c +++ b/ext/thread/thread.c @@ -390,7 +390,7 @@ rb_mutex_try_lock(VALUE self) * */ -static void +static VALUE lock_mutex(Mutex *mutex) { VALUE current; @@ -405,6 +405,7 @@ lock_mutex(Mutex *mutex) mutex->owner = current; rb_thread_critical = 0; + return Qnil; } static VALUE @@ -623,18 +624,12 @@ static void wait_condvar(ConditionVariable *condvar, Mutex *mutex) { rb_thread_critical = 1; - if (!RTEST(mutex->owner)) { + if (rb_thread_current() != mutex->owner) { rb_thread_critical = 0; - return; + rb_raise(rb_eThreadError, "not owner of the synchronization mutex"); } - if (mutex->owner != rb_thread_current()) { - rb_thread_critical = 0; - rb_raise(rb_eThreadError, "Not owner"); - } - mutex->owner = Qnil; - wait_list(&condvar->waiting); - - lock_mutex(mutex); + unlock_mutex_inner(mutex); + rb_ensure(wait_list, (VALUE)&condvar->waiting, lock_mutex, (VALUE)mutex); } static VALUE |
