diff options
| author | take_cheeze <[email protected]> | 2014-03-21 06:16:40 +0900 |
|---|---|---|
| committer | take_cheeze <[email protected]> | 2014-03-21 22:10:47 +0900 |
| commit | d4d4f1b0d57bed96bb3341c2304e39afefa352c5 (patch) | |
| tree | 7b5b2abe9d0c4a2054793b50c06b59f09441efb7 /mrbgems/mruby-fiber | |
| parent | 07bd65ae65ba1092191f5a702ce3c15aaca2ab5f (diff) | |
| download | mruby-d4d4f1b0d57bed96bb3341c2304e39afefa352c5.tar.gz mruby-d4d4f1b0d57bed96bb3341c2304e39afefa352c5.zip | |
implement Fiber#transfer
Diffstat (limited to 'mrbgems/mruby-fiber')
| -rw-r--r-- | mrbgems/mruby-fiber/src/fiber.c | 13 | ||||
| -rw-r--r-- | mrbgems/mruby-fiber/test/fiber.rb | 19 |
2 files changed, 32 insertions, 0 deletions
diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 433b11693..b5f9b69dc 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -226,6 +226,18 @@ fiber_eq(mrb_state *mrb, mrb_value self) return mrb_bool_value(fiber_ptr(self) == fiber_ptr(other)); } +static mrb_value +fiber_transfer(mrb_state *mrb, mrb_value self) +{ + mrb_value result = fiber_resume(mrb, self); + + mrb_assert(mrb->c->prev); + mrb_assert(mrb->c->prev->prev); + mrb->c->prev->status = MRB_FIBER_SUSPENDED; + mrb->c->prev = mrb->c->prev->prev; + + return result; +} mrb_value mrb_fiber_yield(mrb_state *mrb, int len, mrb_value *a) @@ -300,6 +312,7 @@ mrb_mruby_fiber_gem_init(mrb_state* mrb) mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE()); mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY()); + mrb_define_method(mrb, c, "transfer", fiber_transfer, MRB_ARGS_ANY()); mrb_define_method(mrb, c, "alive?", fiber_alive_p, MRB_ARGS_NONE()); mrb_define_method(mrb, c, "==", fiber_eq, MRB_ARGS_REQ(1)); diff --git a/mrbgems/mruby-fiber/test/fiber.rb b/mrbgems/mruby-fiber/test/fiber.rb index e10878bf4..c6f9d821f 100644 --- a/mrbgems/mruby-fiber/test/fiber.rb +++ b/mrbgems/mruby-fiber/test/fiber.rb @@ -8,6 +8,25 @@ assert('Fiber#resume') { f.resume(2) } +assert('Fiber#transfer') do + f1 = Fiber.new do |v| + assert_raise(FiberError) { Fiber.current.transfer } + Fiber.yield v + end + f2 = Fiber.new do + f1.transfer(1) + Fiber.yield 2 + end + assert_equal 1, f2.resume + assert_equal 2, f2.resume + f1.resume + f2.resume + assert_false f1.alive? + assert_false f2.alive? + + assert_raise(FiberError) { Fiber.current.transfer } +end + assert('Fiber#alive?') { f = Fiber.new{ Fiber.yield } f.resume |
