Skip to content

TypeError: wrong argument type nil (expected Data) when processing a detached watcher #87

@Watson1978

Description

@Watson1978

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
end

Result

$ 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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions