From: Eric Wong Date: 2009-11-23T11:31:09+09:00 Subject: Re: issues with Kernel#select Tim Pease wrote: > On Nov 21, 2009, at 3:43 PM, Eric Wong wrote: > > Tim Pease wrote: > >> Waking up a thread that is waiting in Kernel#select does not appear to work in ruby 1.9 Can someone please confirm that this is the case. Is this the intended behavior, or is this a bug? > >> > >> > >>> cat a.rb > >> require 'socket' > >> > >> pair = Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) > >> t = Thread.new { > >> Kernel.select pair, nil, nil, nil > >> puts "Thread is about to exit ..." > >> } > >> t.wakeup > >> t.join > >> > >>> ruby --version > >> ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10] > >> > >>> ruby a.rb > >> Thread is about to exit ... > >> > >>> ruby1.9 --version > >> ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10] > >> > >>> ruby1.9 a.rb #=> hangs forever!!!! > >> > >> > >> > >> Any thoughts out there ??? > > > > Hi Tim, > > > > 1.9 is actually doing what I expect it to do, that is waiting > > indefinitely because the timeout argument for select is nil. I might > > consider the 1.8.7 behavior a bug, but then again the underlying > > select(2) syscall is allowed to have spurious wakeups. So even without > > a timeout argument, select may always return even when nothing is > > readable. > > Thanks for the answer. My suspicion is that the Ruby 1.8 green threads > can be woken up, but the Ruby 1.9 system threads "do the right thing"; > hence, the discrepancy in observed behavior. Good to know that it's > not a bug in 1.9. > > /me goes off to rework code Yeah, I expect thread.wakeup to only work on thread-aware things like sleeping on a condition variable or Thread.sleep. 1.8 wraps select() and uses that as the basis of its green thread implementation, so its harder to get around spurious wakeups. For reliably waking up IO#select I'd just write a byte to a pipe (useful with signal handlers, too, see: http://cr.yp.to/docs/selfpipe.html) -- Eric Wong