diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-03-15 15:59:54 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-03-15 15:59:54 +0900 |
| commit | b09b774ddac90bb0c6770cde80ca693d626c2b48 (patch) | |
| tree | 9e4f4340da1d581d5a86f97dc785f394fcd06831 | |
| parent | fc75cff14e7d43defb0c99f5bc9d657c0121c4b0 (diff) | |
| parent | 62f05614eef43c43572c49e771b130d029abbc46 (diff) | |
| download | mruby-b09b774ddac90bb0c6770cde80ca693d626c2b48.tar.gz mruby-b09b774ddac90bb0c6770cde80ca693d626c2b48.zip | |
Merge pull request #1863 from take-cheeze/fiber_double_resume
Add Fiber's double resume test and fix it.
| -rw-r--r-- | include/mruby.h | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-fiber/src/fiber.c | 6 | ||||
| -rw-r--r-- | mrbgems/mruby-fiber/test/fiber.rb | 13 |
3 files changed, 18 insertions, 3 deletions
diff --git a/include/mruby.h b/include/mruby.h index 1acedd161..2cf0a560d 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -70,7 +70,7 @@ typedef struct { enum mrb_fiber_state { MRB_FIBER_CREATED = 0, MRB_FIBER_RUNNING, - MRB_FIBER_RESUMED, + MRB_FIBER_SUSPENDED, MRB_FIBER_TERMINATED, }; diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index f2916e209..a2ce52954 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -161,14 +161,13 @@ 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_RESUMED) { + if (c->status == MRB_FIBER_RUNNING) { 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_RESUMED; if (c->status == MRB_FIBER_CREATED) { mrb_value *b = c->stack+1; mrb_value *e = b + len; @@ -181,6 +180,7 @@ 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; @@ -192,6 +192,7 @@ 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); @@ -227,6 +228,7 @@ mrb_fiber_yield(mrb_state *mrb, int len, mrb_value *a) } c->prev->status = MRB_FIBER_RUNNING; + c->status = MRB_FIBER_SUSPENDED; mrb->c = c->prev; c->prev = NULL; MARK_CONTEXT_MODIFY(mrb->c); diff --git a/mrbgems/mruby-fiber/test/fiber.rb b/mrbgems/mruby-fiber/test/fiber.rb index 8caf7259b..216ad5572 100644 --- a/mrbgems/mruby-fiber/test/fiber.rb +++ b/mrbgems/mruby-fiber/test/fiber.rb @@ -62,3 +62,16 @@ assert('Yield raises when called on root fiber') { true end } + +assert('Double resume of Fiber') do + f1 = Fiber.new {} + f2 = Fiber.new { + f1.resume + assert_raise(RuntimeError) { f2.resume } + Fiber.yield 0 + } + assert_equal 0, f2.resume + f2.resume + assert_false f1.alive? + assert_false f2.alive? +end |
