Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > issues with Kernel#select

Reply
Thread Tools

issues with Kernel#select

 
 
Tim Pease
Guest
Posts: n/a
 
      11-21-2009
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 =3D Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
t =3D 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 #=3D> hangs forever!!!!




Any thoughts out there ???

Blessings,
TwP=

 
Reply With Quote
 
 
 
 
Eric Wong
Guest
Posts: n/a
 
      11-21-2009
Tim Pease <(E-Mail Removed)> 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.

--
Eric Wong

 
Reply With Quote
 
 
 
 
Tim Pease
Guest
Posts: n/a
 
      11-22-2009

On Nov 21, 2009, at 3:43 PM, Eric Wong wrote:

> Tim Pease <(E-Mail Removed)> 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?
>>=20
>>=20
>>> cat a.rb

>> require 'socket'
>>=20
>> pair =3D Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
>> t =3D Thread.new {
>> Kernel.select pair, nil, nil, nil
>> puts "Thread is about to exit ..."
>> }
>> t.wakeup
>> t.join
>>=20
>>> ruby --version

>> ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
>>=20
>>> ruby a.rb

>> Thread is about to exit ...
>>=20
>>> ruby1.9 --version

>> ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10]
>>=20
>>> ruby1.9 a.rb #=3D> hangs forever!!!!

>>=20
>>=20
>>=20
>> Any thoughts out there ???

>=20
> Hi Tim,
>=20
> 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

Blessings,
TwP=

 
Reply With Quote
 
Eric Wong
Guest
Posts: n/a
 
      11-23-2009
Tim Pease <(E-Mail Removed)> wrote:
> On Nov 21, 2009, at 3:43 PM, Eric Wong wrote:
> > Tim Pease <(E-Mail Removed)> 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

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      11-23-2009
2009/11/23 Eric Wong <(E-Mail Removed)>:
> Tim Pease <(E-Mail Removed)> wrote:


>> 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. =A01.8 wraps select()
> and uses that as the basis of its green thread implementation, so its
> harder to get around spurious wakeups. =A0For reliably waking up IO#selec=

t
> I'd just write a byte to a pipe (useful with signal handlers, too, see:
> http://cr.yp.to/docs/selfpipe.html)


Another approach would be to use #select with a timeout and regularly
check some condition.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 
Reply With Quote
 
Tim Pease
Guest
Posts: n/a
 
      11-23-2009

On Nov 23, 2009, at 3:02 AM, Robert Klemme wrote:

> 2009/11/23 Eric Wong <(E-Mail Removed)>:
>> Tim Pease <(E-Mail Removed)> wrote:

>=20
>>> 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.
>>>=20
>>> /me goes off to rework code

>>=20
>> 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)

>=20
> Another approach would be to use #select with a timeout and regularly
> check some condition.
>=20


Are you done yet? Are you done yet? Are you done yet? Are you done yet?

I thought about that, but it's a little more code than I want to write. =
And I'd like my programs to *not* act like my 3 year old when he's tired =
Closing the socket is my solution. This is shutdown code ... just =
need my thread back so I can do some cleanup.

Thanks for the input.

Blessings,
TwP=

 
Reply With Quote
 
Tim Pease
Guest
Posts: n/a
 
      11-23-2009

On Nov 22, 2009, at 7:31 PM, Eric Wong wrote:

> Tim Pease <(E-Mail Removed)> wrote:
>> On Nov 21, 2009, at 3:43 PM, Eric Wong wrote:
>>> Tim Pease <(E-Mail Removed)> 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?
>>>>=20
>>>>=20
>>>>> cat a.rb
>>>> require 'socket'
>>>>=20
>>>> pair =3D Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
>>>> t =3D Thread.new {
>>>> Kernel.select pair, nil, nil, nil
>>>> puts "Thread is about to exit ..."
>>>> }
>>>> t.wakeup
>>>> t.join
>>>>=20
>>>>> ruby --version
>>>> ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
>>>>=20
>>>>> ruby a.rb
>>>> Thread is about to exit ...
>>>>=20
>>>>> ruby1.9 --version
>>>> ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10]
>>>>=20
>>>>> ruby1.9 a.rb #=3D> hangs forever!!!!
>>>>=20
>>>>=20
>>>>=20
>>>> Any thoughts out there ???
>>>=20
>>> Hi Tim,
>>>=20
>>> 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.

>>=20
>> 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.
>>=20
>> /me goes off to rework code

>=20
> 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)
>=20


Oooooohhhhh ... rainbows and unicorns, indeed!! Great link.

/me goes off to rework code (again)

Blessings,
TwP=

 
Reply With Quote
 
Tim Pease
Guest
Posts: n/a
 
      11-23-2009

On Nov 22, 2009, at 7:31 PM, Eric Wong wrote:

> Tim Pease <(E-Mail Removed)> wrote:
>> On Nov 21, 2009, at 3:43 PM, Eric Wong wrote:
>>> Tim Pease <(E-Mail Removed)> 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?
>>>>=20
>>>>=20
>>>>> cat a.rb
>>>> require 'socket'
>>>>=20
>>>> pair =3D Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
>>>> t =3D Thread.new {
>>>> Kernel.select pair, nil, nil, nil
>>>> puts "Thread is about to exit ..."
>>>> }
>>>> t.wakeup
>>>> t.join
>>>>=20
>>>>> ruby --version
>>>> ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
>>>>=20
>>>>> ruby a.rb
>>>> Thread is about to exit ...
>>>>=20
>>>>> ruby1.9 --version
>>>> ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-darwin10]
>>>>=20
>>>>> ruby1.9 a.rb #=3D> hangs forever!!!!
>>>>=20
>>>>=20
>>>>=20
>>>> Any thoughts out there ???
>>>=20
>>> Hi Tim,
>>>=20
>>> 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.

>>=20
>> 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.
>>=20
>> /me goes off to rework code

>=20
> 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)
>=20


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


 
Reply With Quote
 
Eric Wong
Guest
Posts: n/a
 
      11-24-2009
Tim Pease <(E-Mail Removed)> wrote:
> On Nov 22, 2009, at 7:31 PM, Eric Wong wrote:
> > Tim Pease <(E-Mail Removed)> wrote:
> > 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


Hi Tim,

I think a length argument is is required for read_nonblock. And
you should probably only be reading from the receiver *after* the
select.

Also, the creation/check of Thread#[:select_signal_pipe] is
potentially racy. I would probably create it in the parent
like this:

pipe = IO.pipe
thr = Thread.new(pipe) do |pipe|
Thread.current[:select_signal_pipe] = pipe
pipe.last.syswrite('.') # wakeup parent once we know the parent can use it
# ...
end
pipe.first.readpartial 1 # blocks until it reads '.'
# after the readpartial, we know the following is set:
assert(thr[:select_signal_pipe] == pipe)
# ...

Unlike the self-pipe example, the basic rule of thumb to avoid driving
oneself nuts is that one set of threads/processes only does reads, and
another set only does writes. Reading and writing to one pipe from the
same thread/process anywhere outside of signal handlers gets really
confusing, really quickly :> And even with the self-pipe signal
handlers, all communication is one-way within any given control block.

I'd also be very defensive about spurious select() wakeups (and
Errno::EINTR, too, just in case). Pretty much any syscall that sleeps
like select() including (but not limited to) pthread_cond_wait, poll,
epoll_wait are all *potentially* susceptible to spurious wakeups, so you
could be exiting a thread when you don't intend to.

--
Eric Wong

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Windows XP Pro clean install issues, SP2 issues too... Howie Computer Support 9 07-12-2005 04:47 PM
Windows XP Pro clean install issues, SP2 issues too... Howie Computer Support 0 07-06-2005 07:12 PM
Re: Windows XP Pro clean install issues, SP2 issues too... pcbutts1 Computer Support 0 07-06-2005 04:58 PM
Re: Windows XP Pro clean install issues, SP2 issues too... pcbutts1 Computer Support 0 07-06-2005 04:52 PM
SNMP Issues in Cisco Routers; Vulnerability Issues in TCP =?iso-8859-1?Q?Frisbee=AE?= MCSE 0 04-21-2004 03:00 PM



Advertisments