summaryrefslogtreecommitdiff
path: root/cont.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-06-01 02:21:31 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-06-01 02:21:31 +0000
commit6c743b0e5ab15529af20c89f59582b4483e30066 (patch)
treec2b837bce096d8132c219ac533749141a84290d7 /cont.c
parent4c79d4bee2beda76473144adc39777a8251051c5 (diff)
* 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: svn+ssh://ci.ruby-lang.org/ruby/trunk@23616 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'cont.c')
-rw-r--r--cont.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/cont.c b/cont.c
index 363e913b4f..c0a5dd78ef 100644
--- a/cont.c
+++ b/cont.c
@@ -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");
}