aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--bootstraptest/test_thread.rb14
-rw-r--r--thread.c7
3 files changed, 27 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index cdacfb7ea2..cedb50a235 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Aug 13 05:03:53 2007 Koichi Sasada <ko1@atdot.net>
+
+ * thread.c (rb_thread_raise): check if target thread is
+ thrown by another thread or not. [ruby-dev:31371]
+
+ * bootstraptest/test_thread.rb: add a test for above.
+
Mon Aug 13 04:35:30 2007 Koichi Sasada <ko1@atdot.net>
* compile.c (iseq_peephole_optimize): fix peephole optimization
@@ -5,7 +12,6 @@ Mon Aug 13 04:35:30 2007 Koichi Sasada <ko1@atdot.net>
* bootstraptest/test_syntax.rb: add a test for above.
-
Mon Aug 13 04:02:29 2007 Koichi Sasada <ko1@atdot.net>
* vm_dump.c (debug_print_pre): fix to show control frame count.
diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb
index 64d685fa19..40ccbad497 100644
--- a/bootstraptest/test_thread.rb
+++ b/bootstraptest/test_thread.rb
@@ -169,3 +169,17 @@ assert_equal %q{11}, %q{
Thread.current[:a]
}.value + Thread.current[:a]
}
+assert_equal %q{1000}, %q{
+begin
+ 1000.times do |i|
+ begin
+ Thread.start(Thread.current) {|u| u.raise }
+ raise
+ rescue
+ ensure
+ end
+ end
+rescue
+ 1000
+end
+}, '[ruby-dev:31371]'
diff --git a/thread.c b/thread.c
index 7ff9439cf4..bae2fd7555 100644
--- a/thread.c
+++ b/thread.c
@@ -758,12 +758,17 @@ rb_thread_raise(int argc, VALUE *argv, rb_thread_t *th)
{
VALUE exc;
+ again:
if (rb_thread_dead(th)) {
return Qnil;
}
+ if (th->thrown_errinfo != 0 || th->raised_flag) {
+ rb_thread_schedule();
+ goto again;
+ }
+
exc = rb_make_exception(argc, argv);
- /* TODO: need synchronization if run threads in parallel */
th->thrown_errinfo = exc;
rb_thread_ready(th);
return Qnil;