diff options
| author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-07-04 11:31:35 +0000 |
|---|---|---|
| committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-07-04 11:31:35 +0000 |
| commit | cdd1d98ef27cc54350f1939768f6d827ccd90dd6 (patch) | |
| tree | 75fceff43ecf55e9a40d45954725afa6cbe89acd | |
| parent | 972769ca8eee7c58714b4ef3bdd3fbd6fe3ce4e0 (diff) | |
* eval.c (rb_thread_join): new API.
* ext/thread/thread.c (wait_mutex, lock_mutex): wait until the locking
thread exits. [ruby-dev:34856]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@17874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
| -rw-r--r-- | ChangeLog | 7 | ||||
| -rw-r--r-- | eval.c | 16 | ||||
| -rw-r--r-- | ext/thread/thread.c | 39 |
3 files changed, 46 insertions, 16 deletions
@@ -1,3 +1,10 @@ +Fri Jul 4 20:31:33 2008 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * eval.c (rb_thread_join): new API. + + * ext/thread/thread.c (wait_mutex, lock_mutex): wait until the locking + thread exits. [ruby-dev:34856] + Fri Jul 4 20:20:09 2008 NAKAMURA Usaku <usa@ruby-lang.org> * numeric.c (check_uint): sorry, backport misstake. @@ -11360,10 +11360,10 @@ rb_thread_select(max, read, write, except, timeout) return curr_thread->select_value; } -static int rb_thread_join _((rb_thread_t, double)); +static int rb_thread_join0 _((rb_thread_t, double)); static int -rb_thread_join(th, limit) +rb_thread_join0(th, limit) rb_thread_t th; double limit; { @@ -11405,6 +11405,15 @@ rb_thread_join(th, limit) return Qtrue; } +int +rb_thread_join(thread, limit) + VALUE thread; + double limit; +{ + if (limit < 0) limit = DELAY_INFTY; + return rb_thread_join0(rb_thread_check(thread), limit); +} + /* * call-seq: @@ -11454,11 +11463,10 @@ rb_thread_join_m(argc, argv, thread) { VALUE limit; double delay = DELAY_INFTY; - rb_thread_t th = rb_thread_check(thread); rb_scan_args(argc, argv, "01", &limit); if (!NIL_P(limit)) delay = rb_num2dbl(limit); - if (!rb_thread_join(th, delay)) + if (!rb_thread_join0(rb_thread_check(thread), delay)) return Qnil; return thread; } diff --git a/ext/thread/thread.c b/ext/thread/thread.c index 68f172220a..ac81b2e3ba 100644 --- a/ext/thread/thread.c +++ b/ext/thread/thread.c @@ -242,19 +242,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; } @@ -390,6 +393,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 @@ -410,14 +432,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; |
