mruby-task: switch mrb_task_run to mrb_protect_error

mruby/throw.h is documented as a core-internal header that should not
be included from mrbgems or user code, and under MRB_USE_CXX_EXCEPTION
or MRB_USE_CXX_ABI the MRB_TRY/MRB_CATCH macros expand to C++
exception syntax that does not compile in a C source file. The
wrapping added in #6866 (commit ee82a7fcc6) accidentally tripped that
constraint.

Drop the throw.h include and use mrb_protect_error() from
mruby/error.h instead. The helper takes a body function plus
userdata, runs it under its own jmpbuf, and reports whether an
exception was caught. We re-raise via mrb_exc_raise so the visible
behavior matches the previous code: loop_running is cleared on both
success and exception, and an exception propagates back out.

Refs #6866.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-05-28 12:10:08 +09:00
parent dfc542dbc5
commit c09196ca36
+24 -23
View File
@@ -14,7 +14,6 @@
#include <mruby/internal.h> #include <mruby/internal.h>
#include <mruby/proc.h> #include <mruby/proc.h>
#include <mruby/string.h> #include <mruby/string.h>
#include <mruby/throw.h>
#include <mruby/variable.h> #include <mruby/variable.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
@@ -440,22 +439,14 @@ mrb_tick(mrb_state *mrb)
} }
} }
/* Main scheduler loop */ /* Body of the main scheduler loop. Wrapped by mrb_task_run() under
MRB_API mrb_value mrb_protect_error so an exception raised from a task body unwinds
mrb_task_run(mrb_state *mrb) cleanly without leaving `loop_running` set. */
static mrb_value
task_run_body(mrb_state *mrb, void *ud)
{ {
struct mrb_jmpbuf *prev_jmp;
struct mrb_jmpbuf c_jmp;
mrb_task *t; mrb_task *t;
(void)ud;
if (mrb->task.loop_running) {
return mrb_nil_value();
}
mrb->task.loop_running = TRUE;
prev_jmp = mrb->jmp;
MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
while (1) { while (1) {
t = q_ready_; t = q_ready_;
@@ -492,17 +483,27 @@ mrb_task_run(mrb_state *mrb)
mrb_incremental_gc(mrb); mrb_incremental_gc(mrb);
} }
} }
mrb->jmp = prev_jmp;
} MRB_CATCH(&c_jmp) {
mrb->task.loop_running = FALSE;
mrb->jmp = prev_jmp;
MRB_THROW(prev_jmp);
} MRB_END_EXC(&c_jmp);
mrb->task.loop_running = FALSE;
return mrb_nil_value(); return mrb_nil_value();
} }
/* Main scheduler loop */
MRB_API mrb_value
mrb_task_run(mrb_state *mrb)
{
if (mrb->task.loop_running) {
return mrb_nil_value();
}
mrb->task.loop_running = TRUE;
mrb_bool error = FALSE;
mrb_value result = mrb_protect_error(mrb, task_run_body, NULL, &error);
mrb->task.loop_running = FALSE;
if (error) {
mrb_exc_raise(mrb, result);
}
return result;
}
/* Single-step task execution for WASM event loop integration */ /* Single-step task execution for WASM event loop integration */
MRB_API mrb_value MRB_API mrb_value
mrb_task_run_once(mrb_state *mrb) mrb_task_run_once(mrb_state *mrb)