Forum: Ruby closing a socket while another thread is in an IO.select() call on it

3d7eab71d5986d3b997bc8471f2ce10d?d=identicon&s=25 Graham Menhennitt (Guest)
on 2013-07-15 09:54
(Received via mailing list)
Hello Rubyists,

I have a program that opens a TCPSocket, connects it to a server, and
then creates a thread which loops until the socket closes, reading from
the socket and processing the data read. It calls IO.select() to wait
until there is data available to read. Meanwhile, another thread can
close the socket in certain circumstances. If the first thread is in
IO.select() when the socket is closed, the result is unpredictable -
sometimes the select() returns and sometimes it blocks. I'm not sure of
the circumstances that cause it to block or not - it seems random.

So, is there some way to make it reliably unblock? Or is there something
that the second thread can do to cause the select() to return (set a
flag on the socket before closing it, or something)?

This is with Ruby 2.0.0 p247 on Centos 5 Linux if that's significant.

Thanks in advance for any suggestions.
    Graham
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-07-15 10:32
(Received via mailing list)
On Mon, Jul 15, 2013 at 9:53 AM, Graham Menhennitt
<graham@menhennitt.com.au
> wrote:

> Hello Rubyists,
>
> I have a program that opens a TCPSocket, connects it to a server, and
> then creates a thread which loops until the socket closes, reading from
> the socket and processing the data read. It calls IO.select() to wait
> until there is data available to read.


Why don't you just use a blocking read if you have a separate thread per
socket anyway?  Select is only useful if you want to have a single
thread
process several file descriptors.


> Meanwhile, another thread can
> close the socket in certain circumstances. If the first thread is in
> IO.select() when the socket is closed, the result is unpredictable -
> sometimes the select() returns and sometimes it blocks. I'm not sure of
> the circumstances that cause it to block or not - it seems random.
>

Hmmm.  That sounds a bit odd.  I would have expected select to return.
 Maybe there's a race condition in the std lib.


> So, is there some way to make it reliably unblock? Or is there something
> that the second thread can do to cause the select() to return (set a
> flag on the socket before closing it, or something)?
>

You could work with a timeout but that seems a bit like a workaround.


> This is with Ruby 2.0.0 p247 on Centos 5 Linux if that's significant.
>

Kind regards

robert
3d7eab71d5986d3b997bc8471f2ce10d?d=identicon&s=25 Graham Menhennitt (Guest)
on 2013-07-21 11:24
(Received via mailing list)
On 15/07/2013 18:32, Robert Klemme wrote:
>     from
>     close the socket in certain circumstances. If the first thread is in
>     So, is there some way to make it reliably unblock? Or is there
>
> Kind regards
>
> robert
>
> --
> remember.guy do |as, often| as.you_can - without end
> http://blog.rubybestpractices.com/
Thanks for replying, Robert.

I had actually simplified a bit what I told you about my use case -
there was a reason for using select(). But you're right - I changed the
program to use a blocking read instead, and it now works. I suspect
there's some bug in select(), but I'm not sure how to reproduce it. Yes,
a timeout would probably work, but not very elegant.

Thank for your help,
    Graham
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.