fix: wrap mrb_task_run in MRB_TRY/MRB_CATCH

This commit is contained in:
0x1eef
2026-05-27 23:19:43 -03:00
parent 819156e678
commit ee82a7fcc6
+41 -28
View File
@@ -14,6 +14,7 @@
#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>
@@ -443,6 +444,8 @@ mrb_tick(mrb_state *mrb)
MRB_API mrb_value MRB_API mrb_value
mrb_task_run(mrb_state *mrb) mrb_task_run(mrb_state *mrb)
{ {
struct mrb_jmpbuf *prev_jmp;
struct mrb_jmpbuf c_jmp;
mrb_task *t; mrb_task *t;
if (mrb->task.loop_running) { if (mrb->task.loop_running) {
@@ -450,41 +453,51 @@ mrb_task_run(mrb_state *mrb)
} }
mrb->task.loop_running = TRUE; mrb->task.loop_running = TRUE;
while (1) { prev_jmp = mrb->jmp;
t = q_ready_; MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
/* No task ready - check if all tasks are done */ while (1) {
if (!t) { t = q_ready_;
mrb_task_disable_irq();
mrb_bool exiting = !q_ready_ && !q_waiting_ && !q_suspended_; /* No task ready - check if all tasks are done */
mrb_task_enable_irq(); if (!t) {
if (exiting) { mrb_task_disable_irq();
/* All tasks are dormant - scheduler done */ mrb_bool exiting = !q_ready_ && !q_waiting_ && !q_suspended_;
break; mrb_task_enable_irq();
if (exiting) {
/* All tasks are dormant - scheduler done */
break;
}
/* If there are tasks waiting or suspended, idle */
mrb_hal_task_idle_cpu(mrb);
continue;
} }
/* If there are tasks waiting or suspended, idle */
mrb_hal_task_idle_cpu(mrb);
continue;
}
/* Safety check - don't execute terminated tasks */ /* Safety check - don't execute terminated tasks */
if (task_cleanup_if_stopped(mrb, t)) { if (task_cleanup_if_stopped(mrb, t)) {
continue; continue;
} }
/* Execute task using core logic */ /* Execute task using core logic */
execute_task(mrb, t); execute_task(mrb, t);
/* Move to end of ready queue if still running (round-robin) */ /* Move to end of ready queue if still running (round-robin) */
if (t->status == MRB_TASK_STATUS_READY) { if (t->status == MRB_TASK_STATUS_READY) {
task_change_state(mrb, t, MRB_TASK_STATUS_READY); task_change_state(mrb, t, MRB_TASK_STATUS_READY);
} }
/* Run incremental GC if active */ /* Run incremental GC if active */
if (mrb->gc.state != MRB_GC_STATE_ROOT) { if (mrb->gc.state != MRB_GC_STATE_ROOT) {
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; mrb->task.loop_running = FALSE;
return mrb_nil_value(); return mrb_nil_value();