From 2c7204fc937dc2ae6a8c2de75f508791c30f1de9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 1 Mar 2014 00:48:08 +0900 Subject: mrb_fiber_yield() is available now; you have to link mruby-fiber mrbgem to use the function; there's no function available to create new fiber from C (countapart of Lua's lua_newthread), but that's because you cannot create a new fiber from C due to mruby C API design limitation. define your method to create fibers in Ruby; close #1269 --- include/mruby.h | 3 +++ mrbgems/mruby-fiber/src/fiber.c | 38 +++++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/mruby.h b/include/mruby.h index 30c2dbbb1..4f404fb8e 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -374,6 +374,9 @@ mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id); mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid); mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c); +/* fiber functions (you need to link mruby-fiber mrbgem to use) */ +mrb_value mrb_fiber_yield(mrb_state *mrb, int argc, mrb_value *argv); + /* memory pool implementation */ typedef struct mrb_pool mrb_pool; struct mrb_pool* mrb_pool_open(mrb_state*); diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 6ee22eded..0dbdad871 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -205,23 +205,11 @@ fiber_alive_p(mrb_state *mrb, mrb_value self) return mrb_bool_value(c->status != MRB_FIBER_TERMINATED); } -/* - * call-seq: - * Fiber.yield(args, ...) -> obj - * - * Yields control back to the context that resumed the fiber, passing - * along any arguments that were passed to it. The fiber will resume - * processing at this point when resume is called next. - * Any arguments passed to the next resume will be the - * value that this Fiber.yield expression evaluates to. - */ -static mrb_value -fiber_yield(mrb_state *mrb, mrb_value self) +mrb_value +mrb_fiber_yield(mrb_state *mrb, int len, mrb_value *a) { struct mrb_context *c = mrb->c; mrb_callinfo *ci; - mrb_value *a; - int len; for (ci = c->ci; ci >= c->cibase; ci--) { if (ci->acc < 0) { @@ -231,7 +219,7 @@ fiber_yield(mrb_state *mrb, mrb_value self) if (!c->prev) { mrb_raise(mrb, E_ARGUMENT_ERROR, "can't yield from root fiber"); } - mrb_get_args(mrb, "*", &a, &len); + c->prev->status = MRB_FIBER_RUNNING; mrb->c = c->prev; c->prev = NULL; @@ -239,6 +227,26 @@ fiber_yield(mrb_state *mrb, mrb_value self) return fiber_result(mrb, a, len); } +/* + * call-seq: + * Fiber.yield(args, ...) -> obj + * + * Yields control back to the context that resumed the fiber, passing + * along any arguments that were passed to it. The fiber will resume + * processing at this point when resume is called next. + * Any arguments passed to the next resume will be the + * value that this Fiber.yield expression evaluates to. + */ +static mrb_value +fiber_yield(mrb_state *mrb, mrb_value self) +{ + mrb_value *a; + int len; + + mrb_get_args(mrb, "*", &a, &len); + return mrb_fiber_yield(mrb, len, a); +} + /* * call-seq: * Fiber.current() -> fiber -- cgit v1.2.3