Actions
Bug #21610
closedUse ec->interrupt_mask to prevent interrupts.
Description
The following program can trigger rb_bug
in rb_fiber_scheduler_unblock
:
require 'async/scheduler'
scheduler = Async::Scheduler.new
Fiber.set_scheduler(scheduler)
Signal.trap(:USR1) do
end
q = Thread::Queue.new
Thread.new do
loop do
Ractor.new do
Process.kill(:USR1, $$)
end.join
end
end
Fiber.schedule do
Fiber.schedule do
1.upto(1000000) do |i|
sleep 0.01
q.pop
q.push(1)
puts "1 iter push/pop"
end
end
Fiber.schedule do
1.upto(1000000) do |i|
sleep 0.01
q.push(i)
q.pop
puts "1 iter push/pop#2"
end
end
Fiber.schedule do
gets
exit!
end
end
In brief, when rb_fiber_scheduler_unblock
executes with ec->interrupt_flag
set, the following sequence can occur:
Thread A (Signaling) Thread B (Blocked Fiber)
-------------------- ---------------------
calls unblock(fiber_x)
├─ enters scheduler user code fiber_x sleeping in scheduler.block()
├─ ⚠️ SIGNAL INTERRUPT ⚠️
├─ raises SignalException
├─ unblock operation aborted
├─ scheduler state inconsistent
└─ returns believing success └─ fiber_x waits forever ⚠️
Confirmed fix: https://github.com/ruby/ruby/pull/14588
Updated by ioquatix (Samuel Williams) about 13 hours ago
- Assignee set to ioquatix (Samuel Williams)
- Backport changed from 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED
Updated by ioquatix (Samuel Williams) about 12 hours ago
- Status changed from Open to Closed
Updated by ioquatix (Samuel Williams) about 11 hours ago
A slightly different change may be required for 3.3 and 3.2 backports: https://github.com/ruby/ruby/commit/e900e9fc9ace5e36de5170c83df0f56167e4c8a9
Updated by ioquatix (Samuel Williams) about 11 hours ago
- Backport changed from 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED to 3.2: REQUIRED, 3.3: REQUIRED, 3.4: DONE
Actions
Like0
Like0Like0Like0Like0