Improve memory management of mrb_execute_proc_synchronously

Wrap sync task by mrb_gc_arena_save/restore to release objects from arena
that a sync task allocated so that they can be freed in GC cycle
This commit is contained in:
HASUMI Hitoshi
2026-01-14 14:12:51 +09:00
parent 8a0263026e
commit 63dd1832bc
+6
View File
@@ -1171,6 +1171,7 @@ MRB_API mrb_value
mrb_execute_proc_synchronously(mrb_state *mrb, mrb_value proc_val, mrb_int argc, const mrb_value *argv)
{
struct RProc *proc = mrb_proc_ptr(proc_val);
int ai = mrb_gc_arena_save(mrb);
/* 1. Lock scheduler and save context */
if (mrb->task.scheduler_lock >= MRB_TASK_SCHEDULER_LOCK_MAX) {
@@ -1228,6 +1229,9 @@ mrb_execute_proc_synchronously(mrb_state *mrb, mrb_value proc_val, mrb_int argc,
q_delete_task(mrb, t);
mrb_task_enable_irq();
/* Prevent double-free: clear Data object's type before freeing task */
DATA_TYPE(task_obj) = NULL;
/* Free context resources directly (bypass GC since we own this task) */
if (t->c.stbase) {
mrb_free(mrb, t->c.stbase);
@@ -1243,6 +1247,8 @@ mrb_execute_proc_synchronously(mrb_state *mrb, mrb_value proc_val, mrb_int argc,
mrb->c = original_c;
mrb->task.scheduler_lock--;
mrb_gc_arena_restore(mrb, ai);
return result;
}