-
-
Notifications
You must be signed in to change notification settings - Fork 49
Open
Description
Description
I encountered a TypeError in cool.io gem.
The issue occurs when a watcher is detached while an event for it is already pending in the libev queue (ready to be processed).
If detach is called (e.g., from another thread or a preceding callback in the same loop cycle) before the pending event is processed,
Coolio_Loop_process_event attempts to handle the event for the now-detached watcher.
This causes unexpected TypeError because the watcher's loop reference has already been cleared to nil.
Reproduction Code
The following script uses threads to reliably simulate the race condition where a write event and a detach operation overlap,
causing the event loop to hit a detached watcher.
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'cool.io'
end
class Victim < Cool.io::IOWatcher
def initialize(io)
super
@io = io
end
def on_readable
begin
@io.read_nonblock(1024)
rescue
end
end
end
loop = Cool.io::Loop.default
1000.times do |i|
puts "# Iteration #{i}"
r_victim, w_victim = IO.pipe
victim_watcher = Victim.new(r_victim)
victim_watcher.attach(loop)
Thread.new do
sleep 0.01
w_victim.write("dummy\n")
end
Thread.new do
sleep 0.01
victim_watcher.detach
end
loop.run_once
r_victim.close
w_victim.close
endResult
$ ruby -v coolio.rb
ruby 3.4.8 (2025-12-17 revision 995b59f666) +PRISM [x86_64-linux]
# Iteration 0
# Iteration 1
# Iteration 2
# Iteration 3
# Iteration 4
# Iteration 5
...
# Iteration 95
# Iteration 96
coolio.rb:40:in 'Coolio::Loop#run_once': wrong argument type nil (expected Coolio::Loop) (TypeError)
from coolio.rb:40:in 'block in <main>'
from <internal:numeric>:257:in 'Integer#times'
from coolio.rb:24:in '<main>'
Expected
The reproduction code should be finished with no error.
Metadata
Metadata
Assignees
Labels
No labels