> Issue #8080 has been updated by jonleighton (Jon Leighton).
> normalperson (Eric Wong) wrote:
> > Looking at your workaround, I think a better one is "watcher.to_io"
> > method needs to memoize its return value.
> >
> > I think Ruby expects the return value of obj.to_io to be persistent
> > for the lifetime of obj.
> >
> > Making IO.select cache the value of to_io internally might be alright...
>
> It seems that IO.select *does* cache the value of to_io internally. At least that seems to be the case from
https://gist.github.com/jonleighton/5172263.
>
> Running the script prints "to_io" once and then hangs.
That's because nothing else is running while IO.select is running.
IO.select does not cache, it accesses once the data once.
See comments below:
---------------------------------8<-------------------------------
class Foo
def to_io
puts "to_io"
IO.pipe.first
end
end
n = 0
trap(:USR1) { n += 1 }
# Generate garbage to trigger GC, and then EINTR for select()
Thread.new do
loop do
# make some garbage here
(1..1000000).each { |z| z.to_s.dup }
puts "KILL #{n}"
Process.kill("USR1", $$)
end
end
# This will now return empty arrays
# If you swap Foo.new for $stdin, this will never return (as expected)
p IO.select([Foo.new])
---------------------------------8<-------------------------------