mirror of
https://github.com/ruby/ruby.git
synced 2026-08-02 20:49:12 +08:00
parent
0f5e45d8cf
commit
84a27934cf
Notes:
git
2026-07-17 22:18:53 +00:00
Merged-By: ioquatix <samuel@codeotaku.com>
8
cont.c
8
cont.c
@ -2869,6 +2869,13 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fi
|
||||
|
||||
VM_ASSERT(FIBER_RUNNABLE_P(fiber));
|
||||
|
||||
/*
|
||||
* Keep the target fiber object alive across fiber_store. The raw
|
||||
* rb_fiber_t pointer is used after the coroutine switch, and GC may run
|
||||
* while this C frame is suspended.
|
||||
*/
|
||||
VALUE fiber_value = fiber->cont.self;
|
||||
|
||||
rb_fiber_t *current_fiber = fiber_current();
|
||||
|
||||
VM_ASSERT(!current_fiber->resuming_fiber);
|
||||
@ -2902,6 +2909,7 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fi
|
||||
}
|
||||
}
|
||||
#endif
|
||||
RB_GC_GUARD(fiber_value);
|
||||
|
||||
if (fiber_current()->blocking) {
|
||||
th->blocking += 1;
|
||||
|
||||
@ -497,6 +497,40 @@ class TestFiber < Test::Unit::TestCase
|
||||
assert_equal :ok, ret, '[Bug #14642]'
|
||||
end
|
||||
|
||||
def test_gc_during_nested_resume_yield
|
||||
assert_normal_exit <<-'RUBY', '[Bug #22196]', timeout: 10
|
||||
parent = child1 = child2 = nil
|
||||
|
||||
parent = Fiber.new do
|
||||
child1 = Fiber.new do
|
||||
parent.resume
|
||||
end
|
||||
|
||||
child2 = Fiber.new do
|
||||
GC.start
|
||||
parent.resume
|
||||
end
|
||||
|
||||
Fiber.yield
|
||||
|
||||
child1 = nil
|
||||
|
||||
Fiber.yield
|
||||
end
|
||||
|
||||
parent.resume
|
||||
|
||||
child = child1
|
||||
child1 = nil
|
||||
child.resume
|
||||
child = nil
|
||||
|
||||
child = child2
|
||||
child2 = nil
|
||||
child.resume
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_machine_stack_gc
|
||||
assert_normal_exit <<-RUBY, '[Bug #14561]', timeout: 60
|
||||
enum = Enumerator.new { |y| y << 1 }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user