mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #1863 from take-cheeze/fiber_double_resume
Add Fiber's double resume test and fix it.
This commit is contained in:
+1
-1
@@ -70,7 +70,7 @@ typedef struct {
|
||||
enum mrb_fiber_state {
|
||||
MRB_FIBER_CREATED = 0,
|
||||
MRB_FIBER_RUNNING,
|
||||
MRB_FIBER_RESUMED,
|
||||
MRB_FIBER_SUSPENDED,
|
||||
MRB_FIBER_TERMINATED,
|
||||
};
|
||||
|
||||
|
||||
@@ -161,14 +161,13 @@ fiber_resume(mrb_state *mrb, mrb_value self)
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "can't cross C function boundary");
|
||||
}
|
||||
}
|
||||
if (c->status == MRB_FIBER_RESUMED) {
|
||||
if (c->status == MRB_FIBER_RUNNING) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "double resume");
|
||||
}
|
||||
if (c->status == MRB_FIBER_TERMINATED) {
|
||||
mrb_raise(mrb, E_RUNTIME_ERROR, "resuming dead fiber");
|
||||
}
|
||||
mrb_get_args(mrb, "*", &a, &len);
|
||||
mrb->c->status = MRB_FIBER_RESUMED;
|
||||
if (c->status == MRB_FIBER_CREATED) {
|
||||
mrb_value *b = c->stack+1;
|
||||
mrb_value *e = b + len;
|
||||
@@ -181,6 +180,7 @@ fiber_resume(mrb_state *mrb, mrb_value self)
|
||||
if (c->prev->fib)
|
||||
mrb_field_write_barrier(mrb, (struct RBasic*)c->fib, (struct RBasic*)c->prev->fib);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)c->fib);
|
||||
mrb->c->status = MRB_FIBER_SUSPENDED;
|
||||
c->status = MRB_FIBER_RUNNING;
|
||||
mrb->c = c;
|
||||
|
||||
@@ -192,6 +192,7 @@ fiber_resume(mrb_state *mrb, mrb_value self)
|
||||
if (c->prev->fib)
|
||||
mrb_field_write_barrier(mrb, (struct RBasic*)c->fib, (struct RBasic*)c->prev->fib);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)c->fib);
|
||||
mrb->c->status = MRB_FIBER_SUSPENDED;
|
||||
c->status = MRB_FIBER_RUNNING;
|
||||
mrb->c = c;
|
||||
return fiber_result(mrb, a, len);
|
||||
@@ -227,6 +228,7 @@ mrb_fiber_yield(mrb_state *mrb, int len, mrb_value *a)
|
||||
}
|
||||
|
||||
c->prev->status = MRB_FIBER_RUNNING;
|
||||
c->status = MRB_FIBER_SUSPENDED;
|
||||
mrb->c = c->prev;
|
||||
c->prev = NULL;
|
||||
MARK_CONTEXT_MODIFY(mrb->c);
|
||||
|
||||
@@ -62,3 +62,16 @@ assert('Yield raises when called on root fiber') {
|
||||
true
|
||||
end
|
||||
}
|
||||
|
||||
assert('Double resume of Fiber') do
|
||||
f1 = Fiber.new {}
|
||||
f2 = Fiber.new {
|
||||
f1.resume
|
||||
assert_raise(RuntimeError) { f2.resume }
|
||||
Fiber.yield 0
|
||||
}
|
||||
assert_equal 0, f2.resume
|
||||
f2.resume
|
||||
assert_false f1.alive?
|
||||
assert_false f2.alive?
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user