From: Eric Wong Date: 2013-03-16T08:21:32+09:00 Subject: [ruby-core:53469] Re: [ruby-trunk - Bug #8080] Segfault in rb_fd_set "jonleighton (Jon Leighton)" wrote: > 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<-------------------------------