I have not been able to change the behavior of IO::read() to non-blocking.
Calling the fcntl method and setting the NONBLOCK flag (and/or the NDELAY
flag) has no effect on the behavior of IO::read().
This is on a socket. IO::recv() does not block; however, I can’t use
IO::recv() because I have already used a buffered read method on the file
descriptor. This causes an exception, not just the unpredictable behavior
suggested in the documentation.
More precisely, if running with the debugger, an exception occurs stating that
a previous buffered read has occured on the stream. If running normally
(without the debugger) an exception occurs stating “wrong number of arguments
(5 for 4)” during the IO#read() call, which is odd as the method takes only
one parameter and a second optional parameter. Presumably the exception
occurs somewhere down the stack; as the method name is not displayed and the
behavior changes if the debugger is used, it is rather difficult to know what
is going on.
In any event I need to be able to do a read that doesn’t block.
···
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
Kernel.select ?
Not really what you’re asking for, but…
···
On Thu, Feb 27, 2003 at 05:03:37PM +0900, Seth Kurtzberg wrote:
I have not been able to change the behavior of IO::read() to non-blocking.
Calling the fcntl method and setting the NONBLOCK flag (and/or the NDELAY
flag) has no effect on the behavior of IO::read().
This is on a socket. IO::recv() does not block; however, I can’t use
IO::recv() because I have already used a buffered read method on the file
descriptor. This causes an exception, not just the unpredictable behavior
suggested in the documentation.
More precisely, if running with the debugger, an exception occurs stating that
a previous buffered read has occured on the stream. If running normally
(without the debugger) an exception occurs stating “wrong number of arguments
(5 for 4)” during the IO#read() call, which is odd as the method takes only
one parameter and a second optional parameter. Presumably the exception
occurs somewhere down the stack; as the method name is not displayed and the
behavior changes if the debugger is used, it is rather difficult to know what
is going on.
In any event I need to be able to do a read that doesn’t block.
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Why use Windows when you can have air conditioning?
Why use Windows, when you can leave through the door?
-- Konrad Blum
As I said, I can’t use recv() or sysread() without destroying the design of my
program. There is no good reason that I can’t get non-blocking reads unless
I use recv() or sysread(). The documentation clearly states that I can use
fcntl(), and refers me to the man page for fcntl().
Another possible solution would be to use some sort of PEEK call to find out
how much data is currently available, and then call IO#read() for that amount
of data.
I did verify with strace that the proper fcntl call does occur, with flags
O_RDWR | O_NONBLOCK (O_RDWR set by default and retrieved by an fcntl call
with F_GETFL, and O_NONBLOCK or’d with it). Here is the line from strace:
fcntl64(8, F_SETFL, O_RDWR|O_NONBLOCK) = 0
The call is IO#read(32256), producing this message:
wrong number of arguments(5 for 4)
As I said, using the debugger changes the output, so I can’t get any further
information. I put print statements before and after the read call, to make
sure that the exception is raised on the IO#read() call.
···
On Thursday 27 February 2003 01:16 am, Yukihiro Matsumoto wrote:
Hi,
In message “Unable to do non-blocking read on socket” > > on 03/02/27, Seth Kurtzberg seth@cql.com writes:
I have not been able to change the behavior of IO::read() to non-blocking.
Calling the fcntl method and setting the NONBLOCK flag (and/or the NDELAY
flag) has no effect on the behavior of IO::read().
We need no summary, we need code, and its exact output.
In general, IO#read does lot more than read(2), use IO#sysread or
IO#recv, without mixing other reading methods.
matz.
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
The read call is already preceded by kernel#select(), but that doesn’t help.
kernel#select() tells me that data is available to read, but it doesn’t stop
IO#read() from blocking if it’s buffer size is larger than the amount of data
available to read.
···
On Thursday 27 February 2003 01:24 am, Mauricio Fernández wrote:
On Thu, Feb 27, 2003 at 05:03:37PM +0900, Seth Kurtzberg wrote:
I have not been able to change the behavior of IO::read() to
non-blocking. Calling the fcntl method and setting the NONBLOCK flag
(and/or the NDELAY flag) has no effect on the behavior of IO::read().
This is on a socket. IO::recv() does not block; however, I can’t use
IO::recv() because I have already used a buffered read method on the file
descriptor. This causes an exception, not just the unpredictable
behavior suggested in the documentation.
More precisely, if running with the debugger, an exception occurs stating
that a previous buffered read has occured on the stream. If running
normally (without the debugger) an exception occurs stating “wrong number
of arguments (5 for 4)” during the IO#read() call, which is odd as the
method takes only one parameter and a second optional parameter.
Presumably the exception occurs somewhere down the stack; as the method
name is not displayed and the behavior changes if the debugger is used,
it is rather difficult to know what is going on.
In any event I need to be able to do a read that doesn’t block.
Kernel.select ?
Not really what you’re asking for, but…
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
This is with 1.8 CVS head on linux kernel 2.4.20.
···
On Thursday 27 February 2003 06:03 am, nobu.nokada@softhome.net wrote:
Hi,
At Thu, 27 Feb 2003 17:03:37 +0900, > > Seth Kurtzberg wrote:
This is on a socket. IO::recv() does not block; however, I can’t use
IO::recv() because I have already used a buffered read method on the file
descriptor. This causes an exception, not just the unpredictable
behavior suggested in the documentation.
First, what are the version and the platform?
It’s very system dependent issue, and 1.6 doesn’t support
non-blocking IO well.
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
Yeah, normally I’d use IO#sys_read, but as you cannot here…
Perhaps it’d be helpful to implement IO#read in terms of IO#sys_read to
have both non-blocking buffered / non-blocking, non-buff. semantics (or
better call it IO#nb_read).
Otherwise I don’t think there’s much to do, as IO#read is implemented
with fread() and IO#sys_read with read()…
···
On Thu, Feb 27, 2003 at 05:27:26PM +0900, Seth Kurtzberg wrote:
The read call is already preceded by kernel#select(), but that doesn’t help.
kernel#select() tells me that data is available to read, but it doesn’t stop
IO#read() from blocking if it’s buffer size is larger than the amount of data
available to read.
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Absolutely nothing should be concluded from these figures except that
no conclusion can be drawn from them.
– Joseph L. Brothers, Linux/PowerPC Project)
Hi,
As I said, I can’t use recv() or sysread() without destroying the design of my
program. There is no good reason that I can’t get non-blocking reads unless
I use recv() or sysread(). The documentation clearly states that I can use
fcntl(), and refers me to the man page for fcntl().
I misunderstood you, sorry. But I can’t reproduce your
The call is IO#read(32256), producing this message:
wrong number of arguments(5 for 4)
problem, show us your code.
matz.
···
In message “Re: Unable to do non-blocking read on socket” on 03/02/27, Seth Kurtzberg seth@cql.com writes:
Hi,
This is with 1.8 CVS head on linux kernel 2.4.20.
EAGAIN/EWOULDBLOCK should be handled in 1.8, IO#read with no
arguments for non-blocking IO doesn’t wait unreceived data.
$ ruby server.rb foo &
[1] 13697
$ ruby client.rb foo
“”
$ ruby client.rb foo 3
“hello,”
$ ruby client.rb foo 5
“hello, world”
server.rb (255 Bytes)
client.rb (157 Bytes)
io/nonblock.rb (380 Bytes)
···
At Fri, 28 Feb 2003 01:12:07 +0900, Seth Kurtzberg wrote:
Are you saying that the problem is in the underlying C library?
···
On Thursday 27 February 2003 01:37 am, Mauricio Fernández wrote:
On Thu, Feb 27, 2003 at 05:27:26PM +0900, Seth Kurtzberg wrote:
The read call is already preceded by kernel#select(), but that doesn’t
help. kernel#select() tells me that data is available to read, but it
doesn’t stop IO#read() from blocking if it’s buffer size is larger than
the amount of data available to read.
Yeah, normally I’d use IO#sys_read, but as you cannot here…
Perhaps it’d be helpful to implement IO#read in terms of IO#sys_read to
have both non-blocking buffered / non-blocking, non-buff. semantics (or
better call it IO#nb_read).
Otherwise I don’t think there’s much to do, as IO#read is implemented
with fread() and IO#sys_read with read()…
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
It appears that the only alternative is to write my owned buffered read and
line oriented read (such as gets()), which really seems like reinventing the
wheel, and an elderly wheel at that.
···
On Thursday 27 February 2003 01:37 am, Mauricio Fernández wrote:
On Thu, Feb 27, 2003 at 05:27:26PM +0900, Seth Kurtzberg wrote:
The read call is already preceded by kernel#select(), but that doesn’t
help. kernel#select() tells me that data is available to read, but it
doesn’t stop IO#read() from blocking if it’s buffer size is larger than
the amount of data available to read.
Yeah, normally I’d use IO#sys_read, but as you cannot here…
Perhaps it’d be helpful to implement IO#read in terms of IO#sys_read to
have both non-blocking buffered / non-blocking, non-buff. semantics (or
better call it IO#nb_read).
Otherwise I don’t think there’s much to do, as IO#read is implemented
with fread() and IO#sys_read with read()…
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
Do you mean that this was changed, or that it should have worked like this
already?
···
On Sunday 02 March 2003 02:27 am, nobu.nokada@softhome.net wrote:
Hi,
At Fri, 28 Feb 2003 01:12:07 +0900, > > Seth Kurtzberg wrote:
This is with 1.8 CVS head on linux kernel 2.4.20.
EAGAIN/EWOULDBLOCK should be handled in 1.8, IO#read with no
arguments for non-blocking IO doesn’t wait unreceived data.
$ ruby server.rb foo &
[1] 13697
$ ruby client.rb foo
“”
$ ruby client.rb foo 3
“hello,”
$ ruby client.rb foo 5
“hello, world”
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
I guess I must be missing something, but I see nothing here that would expose
a blocking read if in fact one were occuring.
Also, the blocking behavior only occurs when the maximum read size argument is
supplied to the read() call.
···
On Sunday 02 March 2003 02:27 am, nobu.nokada@softhome.net wrote:
Hi,
At Fri, 28 Feb 2003 01:12:07 +0900, > > Seth Kurtzberg wrote:
This is with 1.8 CVS head on linux kernel 2.4.20.
EAGAIN/EWOULDBLOCK should be handled in 1.8, IO#read with no
arguments for non-blocking IO doesn’t wait unreceived data.
$ ruby server.rb foo &
[1] 13697
$ ruby client.rb foo
“”
$ ruby client.rb foo 3
“hello,”
$ ruby client.rb foo 5
“hello, world”
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
Matz,
I tracked down one reason why we are seeing different behavior. I was
following the documentation which specifies that the Fcntl constants should
be used on an fcntl call (which does seem reasonable). In addition, the the
socket source file in Ruby, O_NDELAY is also used.
You are using File::NONBLOCK. And, indeed, File::NONBLOCK appears to work. I
am still testing so I will let you know if I run into anything else.
···
On Sunday 02 March 2003 02:27 am, nobu.nokada@softhome.net wrote:
Hi,
At Fri, 28 Feb 2003 01:12:07 +0900, > > Seth Kurtzberg wrote:
This is with 1.8 CVS head on linux kernel 2.4.20.
EAGAIN/EWOULDBLOCK should be handled in 1.8, IO#read with no
arguments for non-blocking IO doesn’t wait unreceived data.
$ ruby server.rb foo &
[1] 13697
$ ruby client.rb foo
“”
$ ruby client.rb foo 3
“hello,”
$ ruby client.rb foo 5
“hello, world”
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
What would be the way to read all the data currently available, without
blocking (waiting for more)?
The only solution I can thing of without using #sysread is using select and
reading only one byte at a time, then repeating until there’s nothing
left, but this is so sloow…
···
On Mon, Mar 03, 2003 at 02:04:21AM +0900, Yukihiro Matsumoto wrote:
Hi,
In message “Re: Unable to do non-blocking read on socket” > on 03/03/03, Seth Kurtzberg seth@cql.com writes:
Also, the blocking behavior only occurs when the maximum read size argument is
supplied to the read() call.
IO#read without maximum size is supposed to read all data from the
port, so that it should naturally block.
–
_ _
__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_
_ \ / ` | ’ \
) | (| | |__ \ | | | | | (| | | | |
.__/ _,|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
Steal my cash, car and TV - but leave the computer!
– Soenke Lange soenke@escher.north.de
Yes, I know, but what I said is the reverse. It blocks when you do supply
the maximum read size, not when you don’t.
···
On Sunday 02 March 2003 10:04 am, Yukihiro Matsumoto wrote:
Hi,
In message “Re: Unable to do non-blocking read on socket” > > on 03/03/03, Seth Kurtzberg seth@cql.com writes:
Also, the blocking behavior only occurs when the maximum read size
argument is supplied to the read() call.
IO#read without maximum size is supposed to read all data from the
port, so that it should naturally block.
matz.
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com
I’ve coded a workaround for this. It is a bit of a hack but appears to work.
I will post it later today.
···
On Sunday 02 March 2003 10:31 am, Mauricio Fernández wrote:
On Mon, Mar 03, 2003 at 02:04:21AM +0900, Yukihiro Matsumoto wrote:
Hi,
In message “Re: Unable to do non-blocking read on socket” > > > > on 03/03/03, Seth Kurtzberg seth@cql.com writes:
Also, the blocking behavior only occurs when the maximum read size
argument is supplied to the read() call.
IO#read without maximum size is supposed to read all data from the
port, so that it should naturally block.
What would be the way to read all the data currently available, without
blocking (waiting for more)?
The only solution I can thing of without using #sysread is using select and
reading only one byte at a time, then repeating until there’s nothing
left, but this is so sloow…
–
Seth Kurtzberg
M. I. S. Corp.
480-661-1849
seth@cql.com