From 63dd1832bc7db484e32e59d26528c5cc07d38789 Mon Sep 17 00:00:00 2001 From: HASUMI Hitoshi Date: Wed, 14 Jan 2026 14:12:51 +0900 Subject: [PATCH] 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 --- mrbgems/mruby-task/src/task.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mrbgems/mruby-task/src/task.c b/mrbgems/mruby-task/src/task.c index 711bee15d..81c5aafe2 100644 --- a/mrbgems/mruby-task/src/task.c +++ b/mrbgems/mruby-task/src/task.c @@ -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; }