fiber_scheduler icon indicating copy to clipboard operation
fiber_scheduler copied to clipboard

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

Open ashtneoi opened this issue 2 years ago • 1 comments

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:

  • when t.join 3 returns quickly, it's because FiberScheduler::Selector#select called IO.select([], [], nil, 0)
  • when t.join 3 returns after 3 seconds, it's because FiberScheduler::Selector#select called IO.select([], [], nil, 3)

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 avatar Jul 23 '22 06:07 ashtneoi

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)

ashtneoi avatar Aug 07 '22 05:08 ashtneoi