Closing a socket while another thread is in an IO.select() call on it

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

On Mon, Jul 15, 2013 at 9:53 AM, Graham Menhennitt
<[email protected]

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

On 15/07/2013 18:32, Robert K. 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