Prefer to use Fiber#transfer in scheduler implementation. (#10479)

This commit is contained in:
Samuel Williams 2024-04-07 19:57:15 +12:00 committed by GitHub
parent ed4d03ea41
commit bdb1fc1e5b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 9 deletions

View File

@ -27,7 +27,9 @@ class Scheduler
Warning[:experimental] = experimental Warning[:experimental] = experimental
end end
def initialize def initialize(fiber = Fiber.current)
@fiber = fiber
@readable = {} @readable = {}
@writable = {} @writable = {}
@waiting = {} @waiting = {}
@ -45,6 +47,10 @@ class Scheduler
attr :writable attr :writable
attr :waiting attr :waiting
def transfer
@fiber.transfer
end
def next_timeout def next_timeout
_fiber, timeout = @waiting.min_by{|key, value| value} _fiber, timeout = @waiting.min_by{|key, value| value}
@ -88,7 +94,7 @@ class Scheduler
end end
selected.each do |fiber, events| selected.each do |fiber, events|
fiber.resume(events) fiber.transfer(events)
end end
if @waiting.any? if @waiting.any?
@ -98,7 +104,7 @@ class Scheduler
waiting.each do |fiber, timeout| waiting.each do |fiber, timeout|
if fiber.alive? if fiber.alive?
if timeout <= time if timeout <= time
fiber.resume fiber.transfer
else else
@waiting[fiber] = timeout @waiting[fiber] = timeout
end end
@ -114,7 +120,7 @@ class Scheduler
end end
ready.each do |fiber| ready.each do |fiber|
fiber.resume fiber.transfer
end end
end end
end end
@ -217,7 +223,7 @@ class Scheduler
@waiting[fiber] = current_time + duration @waiting[fiber] = current_time + duration
end end
Fiber.yield @fiber.transfer
ensure ensure
@waiting.delete(fiber) if duration @waiting.delete(fiber) if duration
@readable.delete(io) if readable @readable.delete(io) if readable
@ -254,7 +260,7 @@ class Scheduler
if timeout if timeout
@waiting[fiber] = current_time + timeout @waiting[fiber] = current_time + timeout
begin begin
Fiber.yield @fiber.transfer
ensure ensure
# Remove from @waiting in the case #unblock was called before the timeout expired: # Remove from @waiting in the case #unblock was called before the timeout expired:
@waiting.delete(fiber) @waiting.delete(fiber)
@ -262,7 +268,7 @@ class Scheduler
else else
@blocking[fiber] = true @blocking[fiber] = true
begin begin
Fiber.yield @fiber.transfer
ensure ensure
@blocking.delete(fiber) @blocking.delete(fiber)
end end
@ -290,7 +296,7 @@ class Scheduler
def fiber(&block) def fiber(&block)
fiber = Fiber.new(blocking: false, &block) fiber = Fiber.new(blocking: false, &block)
fiber.resume fiber.transfer
return fiber return fiber
end end

View File

@ -207,7 +207,7 @@ class TestFiberMutex < Test::Unit::TestCase
Fiber.schedule do Fiber.schedule do
mutex.synchronize do mutex.synchronize do
puts 'in synchronize' puts 'in synchronize'
Fiber.yield scheduler.transfer
end end
end end