summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-03-19 09:08:11 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-03-19 09:08:11 +0900
commitd7eb455cf3a2a4c72ee02fa2907718dd24413169 (patch)
tree24cf8e0ad9d4bc6e5c8392e16ccd708cc1cb46b8
parent72c274473b0facbbca4dde732437924ee8752e99 (diff)
parentd9107fd157111ef1bdb39304534ec877fd815a83 (diff)
downloadmruby-d7eb455cf3a2a4c72ee02fa2907718dd24413169.tar.gz
mruby-d7eb455cf3a2a4c72ee02fa2907718dd24413169.zip
Merge branch 'master' of github.com:mruby/mruby
-rw-r--r--include/mruby.h1
-rw-r--r--mrbgems/mruby-fiber/src/fiber.c5
-rw-r--r--mrbgems/mruby-fiber/test/fiber.rb16
3 files changed, 18 insertions, 4 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 2b2412a46..ca75d2984 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -70,6 +70,7 @@ typedef struct {
enum mrb_fiber_state {
MRB_FIBER_CREATED = 0,
MRB_FIBER_RUNNING,
+ MRB_FIBER_RESUMING,
MRB_FIBER_SUSPENDED,
MRB_FIBER_TERMINATED,
};
diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c
index 1a166f6f5..0a6e0cdd5 100644
--- a/mrbgems/mruby-fiber/src/fiber.c
+++ b/mrbgems/mruby-fiber/src/fiber.c
@@ -164,13 +164,14 @@ fiber_resume(mrb_state *mrb, mrb_value self)
mrb_raise(mrb, E_ARGUMENT_ERROR, "can't cross C function boundary");
}
}
- if (c->status == MRB_FIBER_RUNNING || (mrb->c->prev && mrb->c->prev != mrb->root_c)) {
+ if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMING) {
mrb_raise(mrb, E_RUNTIME_ERROR, "double resume");
}
if (c->status == MRB_FIBER_TERMINATED) {
mrb_raise(mrb, E_RUNTIME_ERROR, "resuming dead fiber");
}
mrb_get_args(mrb, "*", &a, &len);
+ mrb->c->status = MRB_FIBER_RESUMING;
if (c->status == MRB_FIBER_CREATED) {
mrb_value *b = c->stack+1;
mrb_value *e = b + len;
@@ -183,7 +184,6 @@ fiber_resume(mrb_state *mrb, mrb_value self)
if (c->prev->fib)
mrb_field_write_barrier(mrb, (struct RBasic*)c->fib, (struct RBasic*)c->prev->fib);
mrb_write_barrier(mrb, (struct RBasic*)c->fib);
- mrb->c->status = MRB_FIBER_SUSPENDED;
c->status = MRB_FIBER_RUNNING;
mrb->c = c;
@@ -195,7 +195,6 @@ fiber_resume(mrb_state *mrb, mrb_value self)
if (c->prev->fib)
mrb_field_write_barrier(mrb, (struct RBasic*)c->fib, (struct RBasic*)c->prev->fib);
mrb_write_barrier(mrb, (struct RBasic*)c->fib);
- mrb->c->status = MRB_FIBER_SUSPENDED;
c->status = MRB_FIBER_RUNNING;
mrb->c = c;
return fiber_result(mrb, a, len);
diff --git a/mrbgems/mruby-fiber/test/fiber.rb b/mrbgems/mruby-fiber/test/fiber.rb
index 8838208f6..c09b49925 100644
--- a/mrbgems/mruby-fiber/test/fiber.rb
+++ b/mrbgems/mruby-fiber/test/fiber.rb
@@ -96,8 +96,22 @@ assert('Recursive resume of Fiber') do
f1.resume
Fiber.yield 0
}
- assert_equal 0, f2.resume
+ f3 = Fiber.new {
+ f2.resume
+ }
+ assert_equal 0, f3.resume
f2.resume
assert_false f1.alive?
assert_false f2.alive?
+ assert_false f3.alive?
+end
+
+assert('Root fiber resume') do
+ root = Fiber.current
+ assert_raise(RuntimeError) { root.resume }
+ f = Fiber.new {
+ assert_raise(RuntimeError) { root.resume }
+ }
+ f.resume
+ assert_false f.alive?
end