diff options
| author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-06-01 02:21:31 +0000 |
|---|---|---|
| committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-06-01 02:21:31 +0000 |
| commit | b5da94001fb4a9bd35832242d10a988298e62463 (patch) | |
| tree | c2b837bce096d8132c219ac533749141a84290d7 | |
| parent | 9ea580eec7cde7dde9a8122667c73d8503c8e25a (diff) | |
| download | ruby-b5da94001fb4a9bd35832242d10a988298e62463.tar.gz ruby-b5da94001fb4a9bd35832242d10a988298e62463.tar.xz ruby-b5da94001fb4a9bd35832242d10a988298e62463.zip | |
* cont.c (cont_capture, fiber_store): reraise transferred error.
* cont.c (fiber_switch): transfers dead fiber error to the previouse
or root fiber if the current fiber is dead. [ruby-core:23651]
git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@23616 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
| -rw-r--r-- | ChangeLog | 7 | ||||
| -rw-r--r-- | cont.c | 14 | ||||
| -rw-r--r-- | test/ruby/test_fiber.rb | 5 |
3 files changed, 24 insertions, 2 deletions
@@ -1,3 +1,10 @@ +Mon Jun 1 11:21:29 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * cont.c (cont_capture, fiber_store): reraise transferred error. + + * cont.c (fiber_switch): transfers dead fiber error to the previouse + or root fiber if the current fiber is dead. [ruby-core:23651] + Mon Jun 1 10:41:41 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> * include/ruby/intern.h (rb_exc_new2): optimization for literal. @@ -279,6 +279,7 @@ cont_capture(volatile int *stat) VALUE value; value = cont->value; + if (cont->argc == -1) rb_exc_raise(value); cont->value = Qnil; *stat = 1; return value; @@ -850,6 +851,7 @@ fiber_store(rb_fiber_t *next_fib) if (ruby_setjmp(fib->cont.jmpbuf)) { /* restored */ GetFiberPtr(th->fiber, fib); + if (fib->cont.argc == -1) rb_exc_raise(fib->cont.value); return fib->cont.value; } else { @@ -875,7 +877,15 @@ fiber_switch(VALUE fibval, int argc, VALUE *argv, int is_resume) rb_raise(rb_eFiberError, "fiber called across trap"); } else if (fib->status == TERMINATED) { - rb_raise(rb_eFiberError, "dead fiber called"); + value = rb_exc_new2(rb_eFiberError, "dead fiber called"); + if (th->fiber != fibval) rb_exc_raise(value); + fibval = fib->prev; + if (NIL_P(fibval)) fibval = th->root_fiber; + GetFiberPtr(fibval, fib); + cont = &fib->cont; + cont->argc = -1; + cont->value = value; + cont_restore_0(cont, &value); } if (is_resume) { @@ -886,7 +896,7 @@ fiber_switch(VALUE fibval, int argc, VALUE *argv, int is_resume) cont->value = make_passing_arg(argc, argv); if ((value = fiber_store(fib)) == Qundef) { - cont_restore_0(&fib->cont, &value); + cont_restore_0(cont, &value); rb_bug("rb_fiber_resume: unreachable"); } diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb index 6d64ccf72..e6afe55b9 100644 --- a/test/ruby/test_fiber.rb +++ b/test/ruby/test_fiber.rb @@ -173,5 +173,10 @@ class TestFiber < Test::Unit::TestCase fib.resume assert_equal(false, fib.alive?) end + + def test_resume_self + f = Fiber.new {f.resume} + assert_raise(FiberError, '[ruby-core:23651]') {f.transfer} + end end |
