From: Tim Pease Date: 2009-11-24T02:49:45+09:00 Subject: Re: issues with Kernel#select On Nov 22, 2009, at 7:31 PM, Eric Wong wrote: > 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) > Based on the self-pipe page, here is the solution I came up with. Please, anyone, give comments and suggestions. http://gist.github.com/241224 Blessings, TwP