From 2c7204fc937dc2ae6a8c2de75f508791c30f1de9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 1 Mar 2014 00:48:08 +0900 Subject: [PATCH] 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,6 +205,28 @@ fiber_alive_p(mrb_state *mrb, mrb_value self) return mrb_bool_value(c->status != MRB_FIBER_TERMINATED); } +mrb_value +mrb_fiber_yield(mrb_state *mrb, int len, mrb_value *a) +{ + struct mrb_context *c = mrb->c; + mrb_callinfo *ci; + + for (ci = c->ci; ci >= c->cibase; ci--) { + if (ci->acc < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "can't cross C function boundary"); + } + } + if (!c->prev) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "can't yield from root fiber"); + } + + c->prev->status = MRB_FIBER_RUNNING; + mrb->c = c->prev; + c->prev = NULL; + MARK_CONTEXT_MODIFY(mrb->c); + return fiber_result(mrb, a, len); +} + /* * call-seq: * Fiber.yield(args, ...) -> obj @@ -218,25 +240,11 @@ fiber_alive_p(mrb_state *mrb, mrb_value self) static mrb_value fiber_yield(mrb_state *mrb, mrb_value self) { - 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) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "can't cross C function boundary"); - } - } - 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; - MARK_CONTEXT_MODIFY(mrb->c); - return fiber_result(mrb, a, len); + return mrb_fiber_yield(mrb, len, a); } /*