bruno- / fiber_scheduler

Ruby's missing Fiber Scheduler implementation.
MIT License
119 stars 5 forks source link

Thread#join sometimes doesn't wake up when thread terminates #4

Open ashtneoi opened 2 years ago

ashtneoi commented 2 years ago

I'm using fiber_scheduler 0.13.0. Here's my code:

require 'fiber_scheduler'

Fiber.set_scheduler FiberScheduler.new
Fiber.schedule do
    t = Thread.new do
    end
    t.join 3
end

Sometimes t.join 3 returns quickly, which is what I want to happen since thread t almost immediately terminates. However, usually t.join 3 takes 3 seconds to return, which means something (the fiber scheduler, I think) prevented t.join from waking up early.

By adding debug logging to fiber_scheduler, I've figured out two things:

This feels like a bug in fiber_scheduler. Am I right?

(If it matters, I'm using Linux on x86_64, and I installed fiber_scheduler through Bundler.)

ashtneoi commented 2 years ago

Does this patch look like a reasonable fix? It fixes this particular case, at least.

diff --git a/lib/fiber_scheduler/selector.rb b/lib/fiber_scheduler/selector.rb
index 068b390..172f18c 100644
--- a/lib/fiber_scheduler/selector.rb
+++ b/lib/fiber_scheduler/selector.rb
@@ -206,7 +206,7 @@ class FiberScheduler
         end
       end

-      duration = 0 if @ready.any?
+      duration = 0 if @ready.any? or (readable.empty? and writable.empty?)
       readable, writable, _ = IO.select(readable, writable, nil, duration)

       ready = Hash.new(0)