From 14579de431adaf0ad84c619c71c11915518207a6 Mon Sep 17 00:00:00 2001 From: shyouhei Date: Mon, 23 Mar 2009 09:26:03 +0000 Subject: merge revision(s) 17874,17886: * eval.c (rb_thread_join): new API. * ext/thread/thread.c (wait_mutex, lock_mutex): wait until the locking thread exits. [ruby-dev:34856] * eval.c (rb_thread_value): missed to change at r17874. [ruby-core:17595] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_6@23042 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/thread/thread.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'ext') diff --git a/ext/thread/thread.c b/ext/thread/thread.c index bca807725e..ae08a61770 100644 --- a/ext/thread/thread.c +++ b/ext/thread/thread.c @@ -247,19 +247,22 @@ wake_all(List *list) return Qnil; } +extern int rb_thread_join _((VALUE thread, double limit)); +#define DELAY_INFTY 1E30 + static VALUE -wait_list_inner(List *list) +wait_list_inner(VALUE arg) { - push_list(list, rb_thread_current()); + push_list((List *)arg, rb_thread_current()); rb_thread_stop(); return Qnil; } static VALUE -wait_list_cleanup(List *list) +wait_list_cleanup(VALUE arg) { /* cleanup in case of spurious wakeups */ - remove_one(list, rb_thread_current()); + remove_one((List *)arg, rb_thread_current()); return Qnil; } @@ -395,6 +398,25 @@ rb_mutex_try_lock(VALUE self) return Qtrue; } +static VALUE +wait_mutex(VALUE arg) +{ + Mutex *mutex = (Mutex *)arg; + VALUE current = rb_thread_current(); + + push_list(&mutex->waiting, current); + do { + rb_thread_critical = 0; + rb_thread_join(mutex->owner, DELAY_INFTY); + rb_thread_critical = 1; + if (!MUTEX_LOCKED_P(mutex)) { + mutex->owner = current; + break; + } + } while (mutex->owner != current); + return Qnil; +} + /* * Document-method: lock * call-seq: lock @@ -415,14 +437,7 @@ lock_mutex(Mutex *mutex) mutex->owner = current; } else { - do { - wait_list(&mutex->waiting); - rb_thread_critical = 1; - if (!MUTEX_LOCKED_P(mutex)) { - mutex->owner = current; - break; - } - } while (mutex->owner != current); + rb_ensure(wait_mutex, (VALUE)mutex, wait_list_cleanup, (VALUE)&mutex->waiting); } rb_thread_critical = 0; -- cgit v1.2.3