mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-task: fix cooperative task yielding with Task.pass
this patch fixes several critical issues in the task scheduler: 1. vm integration for computed goto dispatch mode: - added task switching check in NEXT macro for computed goto - previous implementation only worked with switch dispatch mode - now Task.pass properly yields control to other tasks 2. task lifecycle tracking: - added 'started' flag to mrb_task structure - fixed first-run detection to avoid popping callinfo multiple times - vm overwrites context status during execution, making it unreliable 3. removed mrblib/task.rb: - empty Ruby method stubs were overriding C implementations - all task methods now properly implemented in C 4. cleaned up task scheduler loop: - proper task completion detection using switching flag - round-robin scheduling for tasks at same priority - clean scheduler exit when all tasks complete tasks now cooperatively yield with Task.pass and complete cleanly. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1523,7 +1523,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const mrb_callinfo *return_ci
|
||||
#define JUMP NEXT
|
||||
#ifdef MRB_USE_TASK_SCHEDULER
|
||||
#define END_DISPATCH L_END_DISPATCH: \
|
||||
if (mrb->task->switching || mrb->c->status == MRB_TASK_STOPPED) \
|
||||
if (mrb->task.switching || mrb->c->status == MRB_TASK_STOPPED) \
|
||||
return mrb_nil_value(); \
|
||||
}}
|
||||
#else
|
||||
@@ -1534,12 +1534,17 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const mrb_callinfo *return_ci
|
||||
|
||||
#define INIT_DISPATCH JUMP; return mrb_nil_value();
|
||||
#define CASE(insn,ops) L_ ## insn: { const mrb_code *pc = ci->pc+1; FETCH_ ## ops (); ci->pc = pc; } L_ ## insn ## _BODY:
|
||||
#ifdef MRB_USE_TASK_SCHEDULER
|
||||
#define NEXT if (mrb->task.switching || mrb->c->status == MRB_TASK_STOPPED) return mrb_nil_value(); \
|
||||
insn=BYTECODE_DECODER(*ci->pc); CODE_FETCH_HOOK(mrb, irep, ci->pc, regs); goto *optable[insn]
|
||||
#else
|
||||
#define NEXT insn=BYTECODE_DECODER(*ci->pc); CODE_FETCH_HOOK(mrb, irep, ci->pc, regs); goto *optable[insn]
|
||||
#endif
|
||||
#define JUMP NEXT
|
||||
|
||||
#ifdef MRB_USE_TASK_SCHEDULER
|
||||
#define END_DISPATCH \
|
||||
if (mrb->task->switching || mrb->c->status == MRB_TASK_STOPPED) \
|
||||
if (mrb->task.switching || mrb->c->status == MRB_TASK_STOPPED) \
|
||||
return mrb_nil_value();
|
||||
#else
|
||||
#define END_DISPATCH
|
||||
@@ -1549,7 +1554,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const mrb_callinfo *return_ci
|
||||
|
||||
#ifdef MRB_USE_TASK_SCHEDULER
|
||||
#define TASK_STOP(mrb) \
|
||||
if (mrb->c->status == MRB_TASK_CREATED) \
|
||||
if (mrb->c->status != MRB_TASK_STOPPED) \
|
||||
mrb->c->status = MRB_TASK_STOPPED;
|
||||
#else
|
||||
#define TASK_STOP(mrb)
|
||||
|
||||
Reference in New Issue
Block a user