diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-09-23 00:01:50 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-09-23 00:01:50 +0000 |
commit | 50b224dd15c5e4aab0d04c5c5ad7d224fbeb1855 (patch) | |
tree | d58048fc2956c1c21f97cdc390a0da894a94f82f | |
parent | 13d5a288271077f74547b803443d821b2cfa0bfb (diff) |
* eval.c, intern.h, ext/thread/thread.c: should not free queue while
any live threads are waiting. [ruby-dev:30653]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_6@13495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | eval.c | 1 | ||||
-rw-r--r-- | ext/thread/thread.c | 50 | ||||
-rw-r--r-- | version.h | 2 |
4 files changed, 25 insertions, 33 deletions
@@ -1,3 +1,8 @@ +Sun Sep 23 07:49:49 2007 Nobuyoshi Nakada <[email protected]> + + * eval.c, intern.h, ext/thread/thread.c: should not free queue while + any live threads are waiting. [ruby-dev:30653] + Sun Sep 23 06:05:35 2007 Nobuyoshi Nakada <[email protected]> * ext/stringio/stringio.c (strio_init): separate from strio_initialize @@ -6825,7 +6825,6 @@ rb_load(fname, wrap) volatile VALUE self = ruby_top_self; NODE *volatile last_node; NODE *saved_cref = ruby_cref; - TMP_PROTECT; if (wrap && ruby_safe_level >= 4) { StringValue(fname); diff --git a/ext/thread/thread.c b/ext/thread/thread.c index 3dba9ba32a..bca807725e 100644 --- a/ext/thread/thread.c +++ b/ext/thread/thread.c @@ -24,11 +24,12 @@ static VALUE rb_cSizedQueue; static VALUE set_critical(VALUE value); static VALUE -thread_exclusive_do(void) +thread_exclusive(VALUE (*func)(ANYARGS), VALUE arg) { - rb_thread_critical = 1; + VALUE critical = rb_thread_critical; - return rb_yield(Qundef); + rb_thread_critical = 1; + return rb_ensure(func, arg, set_critical, (VALUE)critical); } /* @@ -43,7 +44,7 @@ thread_exclusive_do(void) static VALUE rb_thread_exclusive(void) { - return rb_ensure(thread_exclusive_do, Qundef, set_critical, rb_thread_critical); + return thread_exclusive(rb_yield, Qundef); } typedef struct _Entry { @@ -147,7 +148,7 @@ shift_list(List *list) VALUE value; entry = list->entries; - if (!entry) return Qundef; + if (!entry) return Qnil; list->entries = entry->next; if (entry == list->last_entry) { @@ -269,20 +270,12 @@ wait_list(List *list) } static void -assert_no_survivors(List *waiting, const char *label, void *addr) +kill_waiting_threads(List *waiting) { Entry *entry; - VALUE ths = 0; for (entry = waiting->entries; entry; entry = entry->next) { - if (RTEST(wake_thread(entry->value))) { - if (!ths) ths = rb_ary_new(); - rb_ary_push(ths, entry->value); - } - } - if (ths) { - rb_bug("%s %p freed with live thread(s) %s waiting", - label, addr, RSTRING_PTR(rb_inspect(ths))); + rb_thread_kill(entry->value); } } @@ -334,7 +327,7 @@ finalize_mutex(Mutex *mutex) static void free_mutex(Mutex *mutex) { - assert_no_survivors(&mutex->waiting, "mutex", mutex); + kill_waiting_threads(&mutex->waiting); finalize_mutex(mutex); xfree(mutex); } @@ -493,10 +486,8 @@ set_critical(VALUE value) static VALUE unlock_mutex(Mutex *mutex) { - VALUE waking; + VALUE waking = thread_exclusive(unlock_mutex_inner, (VALUE)mutex); - rb_thread_critical = 1; - waking = rb_ensure(unlock_mutex_inner, (VALUE)mutex, set_critical, 0); if (!RTEST(waking)) { return Qfalse; } @@ -544,10 +535,9 @@ rb_mutex_exclusive_unlock(VALUE self) VALUE waking; Data_Get_Struct(self, Mutex, mutex); - rb_thread_critical = 1; - waking = rb_ensure(rb_mutex_exclusive_unlock_inner, (VALUE)mutex, set_critical, 0); + waking = thread_exclusive(rb_mutex_exclusive_unlock_inner, (VALUE)mutex); - if (waking == Qundef || !RTEST(waking)) { + if (!RTEST(waking)) { return Qnil; } @@ -622,7 +612,7 @@ finalize_condvar(ConditionVariable *condvar) static void free_condvar(ConditionVariable *condvar) { - assert_no_survivors(&condvar->waiting, "condition variable", condvar); + kill_waiting_threads(&condvar->waiting); finalize_condvar(condvar); xfree(condvar); } @@ -732,8 +722,7 @@ rb_condvar_broadcast(VALUE self) Data_Get_Struct(self, ConditionVariable, condvar); - rb_thread_critical = 1; - rb_ensure(wake_all, (VALUE)&condvar->waiting, set_critical, 0); + thread_exclusive(wake_all, (VALUE)&condvar->waiting); rb_thread_schedule(); return self; @@ -750,9 +739,8 @@ rb_condvar_broadcast(VALUE self) static void signal_condvar(ConditionVariable *condvar) { - VALUE waking; - rb_thread_critical = 1; - waking = rb_ensure(wake_one, (VALUE)&condvar->waiting, set_critical, 0); + VALUE waking = thread_exclusive(wake_one, (VALUE)&condvar->waiting); + if (RTEST(waking)) { run_thread(waking); } @@ -827,9 +815,9 @@ finalize_queue(Queue *queue) static void free_queue(Queue *queue) { - assert_no_survivors(&queue->mutex.waiting, "queue", queue); - assert_no_survivors(&queue->space_available.waiting, "queue", queue); - assert_no_survivors(&queue->value_available.waiting, "queue", queue); + kill_waiting_threads(&queue->mutex.waiting); + kill_waiting_threads(&queue->space_available.waiting); + kill_waiting_threads(&queue->value_available.waiting); finalize_queue(queue); xfree(queue); } @@ -2,7 +2,7 @@ #define RUBY_RELEASE_DATE "2007-09-23" #define RUBY_VERSION_CODE 186 #define RUBY_RELEASE_CODE 20070923 -#define RUBY_PATCHLEVEL 109 +#define RUBY_PATCHLEVEL 110 #define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MINOR 8 |