diff --git a/ChangeLog b/ChangeLog index ad5015dd31..746275271f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Wed Nov 28 23:39:01 2012 Koichi Sasada + + * thread.c (rb_mutex_sleep): fix to allow spurious wakeup. + + * NEWS: write about spurious wakeup. + Wed Nov 28 23:37:14 2012 Masaya Tarui * NEWS (Thread) remove incompatible changes. diff --git a/NEWS b/NEWS index bca93c1b22..62ad75aae4 100644 --- a/NEWS +++ b/NEWS @@ -116,6 +116,7 @@ with all sufficient information, see the ChangeLog file. * Mutex#lock, Mutex#unlock, Mutex#try_lock, Mutex#synchronize and Mutex#sleep are no longer allowed to be used from trap handler and raise a ThreadError in such case. + * Mutex#sleep may spurious wakeup. Check after wakeup. * NilClass * added method: diff --git a/thread.c b/thread.c index 371607b1fa..0b3d009f0a 100644 --- a/thread.c +++ b/thread.c @@ -4294,15 +4294,15 @@ rb_mutex_abandon_all(rb_mutex_t *mutexes) static VALUE rb_mutex_sleep_forever(VALUE time) { - rb_thread_sleep_deadly(); + sleep_forever(GET_THREAD(), 1, 0); /* permit spurious check */ return Qnil; } static VALUE rb_mutex_wait_for(VALUE time) { - const struct timeval *t = (struct timeval *)time; - rb_thread_wait_for(*t); + struct timeval *t = (struct timeval *)time; + sleep_timeval(GET_THREAD(), *t, 0); /* permit spurious check */ return Qnil; } @@ -4334,6 +4334,9 @@ rb_mutex_sleep(VALUE self, VALUE timeout) * Releases the lock and sleeps +timeout+ seconds if it is given and * non-nil or forever. Raises +ThreadError+ if +mutex+ wasn't locked by * the current thread. + * + * Note that this method can wakeup without explicit Thread#wakeup call. + * For example, receiving signal and so on. */ static VALUE mutex_sleep(int argc, VALUE *argv, VALUE self)