question about IO.select

D

David Miller

Hello all

I was looking at some code in a textmate bundle support library that
wasn't working for me. (I am using e text editor on a XP machine) The
problem appears to be that IO.select is returning a value that I believe
means that data is available to be read, however there does not seem to
be any data available. I have read what I can find about this, but I
don't understand the result I am seeing.

If I run demo code below, IO.select returns immediately. data[0]
contains $stdin, but there are no characters in the stdin buffer so the
getc blocks waiting for input. If I enter several characters and hit
return, the first two characters will show up in the two data[0].getc
statements.

In this example I thought the IO.select would wait for up to 20 seconds
for characters to be available, and return a nil at that time if none
were.

This is a XP box running 1.8.6

What am I missing?

Thanks

Dave M




data, x, x = IO.select([$stdin], nil, nil, 20.0)

puts "$stdin.to_s returns: #{$stdin.to_s}"
puts "$data[0].to_s returns: #{data[0].to_s}"

puts "data[0].getc.to_s returns: #{data[0].getc.chr}"
puts "data[0].getc.to_s returns: #{data[0].getc.chr}"
 
M

Mat Brown

Hello all

I was looking at some code in a textmate bundle support library that
wasn't working for me. =C2=A0(I am using e text editor on a XP machine) = =C2=A0The
problem appears to be that IO.select is returning a value that I believe
means that data is available to be read, however there does not seem to
be any data available. =C2=A0I have read what I can find about this, but = I
don't understand the result I am seeing.

If I run demo code below, IO.select returns immediately. =C2=A0data[0]
contains $stdin, but there are no characters in the stdin buffer so the
getc blocks waiting for input. =C2=A0If I enter several characters and hi= t
return, the first two characters will show up in the two =C2=A0data[0].ge= tc
statements.

In this example I thought the IO.select would wait for up to 20 seconds
for characters to be available, and return a nil at that time if none
were.

This is a XP box running 1.8.6

What am I missing?

Thanks

Dave M




data, x, x =C2=A0=3D IO.select([$stdin], nil, nil, 20.0)

puts "$stdin.to_s returns: #{$stdin.to_s}"
puts "$data[0].to_s returns: #{data[0].to_s}"

puts "data[0].getc.to_s returns: #{data[0].getc.chr}"
puts "data[0].getc.to_s returns: #{data[0].getc.chr}"

Dave,

My experience with IO.select is that if you select on an input stream,
it blocks until the stream is opened for writing by another process,
not until there is actual data to be read. Presumably $stdin is always
going to be open for writing, so IO.select will return immediately. If
you try this on a *nix box, at least, using a FIFO you should see the
same behavior. Unfortunately, IO#select appears to be undocumented in
the Ruby core, but presumably it just passes the call through to the C
function; here's what the linux man pages have to say about the input
argument:

If the readfds argument is not a null pointer, it points to an object
of type fd_set that on input specifies the file descriptors to be
checked for being ready to read, and on output indicates which file
descriptors are ready to read.

Of course, "ready to be read" here is a bit ambiguous, but as I said,
experience suggests that it refers to having been opened for writing,
rather than not having an EOF condition.

Hope that helps,

Mat
 
D

David Miller

Mat said:
My experience with IO.select is that if you select on an input stream,
it blocks until the stream is opened for writing by another process,
not until there is actual data to be read.


Thanks Mat

Actually, I tried it on my linux machine, and it works as I expected.
It blocked for the time period or until I entered some characters
followed by a <cr>. It seems to be different in windows. It makes
sense because the code was in a textmate bundle, and the Mac has *nix
underneath so the code worked in its original environment. I am trying
to run an editor that uses textmate bundles on a windows machine.

I will try it on 1.9.1, and if I get the same result, I will look at the
core which I have never done before. If I do want to look at the core
how do I get started?

Thanks again

Dave
 
D

David Miller

For anyone who cares, this seems to be an issue unique to the 1.8.6
(2007-03-13 patchlevel 0) [i386-mswin32] version of Ruby I have. I have
not tried other patch levels of 1.8.6, but I have tried 1.8.7 and 1.9.1,
and they both work as expected.

Dave
 
R

Robert Klemme

If I run demo code below, IO.select returns immediately. data[0]
contains $stdin, but there are no characters in the stdin buffer so the
getc blocks waiting for input. If I enter several characters and hit
return, the first two characters will show up in the two data[0].getc
statements.

In this example I thought the IO.select would wait for up to 20 seconds
for characters to be available, and return a nil at that time if none
were.
data, x, x = IO.select([$stdin], nil, nil, 20.0)

puts "$stdin.to_s returns: #{$stdin.to_s}"
puts "$data[0].to_s returns: #{data[0].to_s}"

puts "data[0].getc.to_s returns: #{data[0].getc.chr}"
puts "data[0].getc.to_s returns: #{data[0].getc.chr}"
My experience with IO.select is that if you select on an input stream,
it blocks until the stream is opened for writing by another process,
not until there is actual data to be read. Presumably $stdin is always
going to be open for writing, so IO.select will return immediately. If
you try this on a *nix box, at least, using a FIFO you should see the
same behavior. Unfortunately, IO#select appears to be undocumented in
the Ruby core, but presumably it just passes the call through to the C
function; here's what the linux man pages have to say about the input
argument:

If the readfds argument is not a null pointer, it points to an object
of type fd_set that on input specifies the file descriptors to be
checked for being ready to read, and on output indicates which file
descriptors are ready to read.

Of course, "ready to be read" here is a bit ambiguous, but as I said,
experience suggests that it refers to having been opened for writing,
rather than not having an EOF condition.

Normally I would expect "ready for reading" to mean that it is open
*and* there is some data that can be read. Otherwise it does not really
make sense to include such an fd in the set returned.

http://www.manpagez.com/man/2/select/

Having said that I do have experienced "ready for reading" returns if
the other party of a TCP socket connection has closed the socket already
resulting in a 0 byte non blocking read operation. But that seems to be
mostly related to the peculiarities of networks work.

So, under normal conditions select should block until data is actually
readable (when using with a non empty set of descriptors you want to
examine for readability, of course). David's expectations are
absolutely in line with what I would expect and as it turns out this
seems to be a problem of a particular version only.

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top