Revision: 1938 http://trac.macosforge.org/projects/ruby/changeset/1938 Author: lsansonetti@apple.com Date: 2009-06-26 15:10:11 -0700 (Fri, 26 Jun 2009) Log Message: ----------- fixed potential 'signal-before-wait' deadlocks Modified Paths: -------------- MacRuby/branches/experimental/thread.c MacRuby/branches/experimental/vm.cpp Modified: MacRuby/branches/experimental/thread.c =================================================================== --- MacRuby/branches/experimental/thread.c 2009-06-26 19:13:14 UTC (rev 1937) +++ MacRuby/branches/experimental/thread.c 2009-06-26 22:10:11 UTC (rev 1938) @@ -83,8 +83,6 @@ rb_sys_fail("pthread_create() failed"); } - //assert(pthread_detach(t->thread) == 0); - return thread; } Modified: MacRuby/branches/experimental/vm.cpp =================================================================== --- MacRuby/branches/experimental/vm.cpp 2009-06-26 19:13:14 UTC (rev 1937) +++ MacRuby/branches/experimental/vm.cpp 2009-06-26 22:10:11 UTC (rev 1938) @@ -4538,15 +4538,23 @@ post_wait(t); } +static inline void +signal_thread(rb_vm_thread_t *t) +{ + assert(pthread_mutex_lock(&t->sleep_mutex) == 0); + assert(pthread_cond_signal(&t->sleep_cond) == 0); + assert(pthread_mutex_unlock(&t->sleep_mutex) == 0); +} + extern "C" void rb_vm_thread_wakeup(rb_vm_thread_t *t) { if (t->status == THREAD_DEAD) { - rb_raise(rb_eThreadError, "can't wake up thread from the dead"); + rb_raise(rb_eThreadError, "can't wake up thread from the death"); } - if (t->status == THREAD_SLEEP) { - assert(pthread_cond_signal(&t->sleep_cond) == 0); + if (t->status == THREAD_SLEEP && t->in_cond_wait) { + signal_thread(t); } } @@ -4566,7 +4574,7 @@ // will autodestroy itself, to work around a stack unwinding bug // in the Mac OS X pthread implementation that messes our C++ // exception handlers. - assert(pthread_cond_signal(&t->sleep_cond) == 0); + signal_thread(t); } else { assert(pthread_cancel(t->thread) == 0);