From 4f1c1c16da02071007c9d3c7eb4d577ad2502e61 Mon Sep 17 00:00:00 2001 From: dearblue Date: Mon, 4 Dec 2023 22:20:44 +0900 Subject: [PATCH] Check fiber backward when switching with `Fiber#transfer` Previously, if the caller of `Fiber#resume` had a C function call, an inconsistency would occur. --- mrbgems/mruby-fiber/src/fiber.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index f5254a286..9dc151096 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -167,6 +167,17 @@ fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c) } } +static void +fiber_check_cfunc_recursive(mrb_state *mrb, struct mrb_context *c) +{ + for (;; c = c->prev) { + fiber_check_cfunc(mrb, c); + if (c == mrb->root_c || !c->prev) { + break; + } + } +} + static void fiber_switch_context(mrb_state *mrb, struct mrb_context *c) { @@ -370,7 +381,7 @@ fiber_transfer(mrb_state *mrb, mrb_value self) const mrb_value* a; mrb_int len; - fiber_check_cfunc(mrb, mrb->c); + fiber_check_cfunc_recursive(mrb, mrb->c); mrb_get_args(mrb, "*!", &a, &len); if (c->status == MRB_FIBER_RESUMED) {