task: return nil when given a nested call to Task.run

When you try to start an event loop inside an event loop,
the mruby process will SIGSEGV:

```ruby
Task.new { Task.run }
Task.run
```

This change turns the second call to `Task.run` into a noop
that returns nil instead.

Fix #6865
This commit is contained in:
0x1eef
2026-05-27 23:00:45 -03:00
parent d1289ac8f9
commit 819156e678
2 changed files with 8 additions and 0 deletions
+1
View File
@@ -274,6 +274,7 @@ typedef struct mrb_task_state {
volatile mrb_bool switching; /* Context switch pending flag */
struct mrb_task *main_task; /* Main task wrapper for root context */
uint8_t scheduler_lock; /* Lock counter for synchronous execution */
mrb_bool loop_running; /* Active mrb_task_run loop flag */
} mrb_task_state;
#endif
+7
View File
@@ -445,6 +445,11 @@ mrb_task_run(mrb_state *mrb)
{
mrb_task *t;
if (mrb->task.loop_running) {
return mrb_nil_value();
}
mrb->task.loop_running = TRUE;
while (1) {
t = q_ready_;
@@ -481,6 +486,7 @@ mrb_task_run(mrb_state *mrb)
}
}
mrb->task.loop_running = FALSE;
return mrb_nil_value();
}
@@ -1505,6 +1511,7 @@ mrb_mruby_task_gem_init(mrb_state *mrb)
/* Initialize main task to NULL and scheduler_lock to 0 */
mrb->task.main_task = NULL;
mrb->task.scheduler_lock = 0;
mrb->task.loop_running = FALSE;
task_class = mrb_define_class_id(mrb, MRB_SYM(Task), mrb->object_class);
MRB_SET_INSTANCE_TT(task_class, MRB_TT_DATA);