[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: nonblocking read

From: Pawel Kot
Subject: Re: nonblocking read
Date: Tue, 13 Nov 2007 00:15:17 +0100


On Nov 12, 2007 11:33 PM, Baurzhan Ismagulov <address@hidden> wrote:
> On Sun, Nov 11, 2007 at 01:57:13PM +0100, Pawel Kot wrote:
> > > > gnokii uses:
> > > > if (select(...) > 0)
> > > >   read(...);
> > > > sequence to read from the file descriptor.  In case of bluetooth
> > > > connection there may happen that gnokii/xgnokii/whatever is running
> > > > and sending requests and then suddenly gets out of range. So what
> > > > happenes there is that select() returns 1 and read() hands.
> > >
> > > IIUC, this should not happen. The select(2) man page on my Linux system
> > > says: "select()... allows a program to monitor multiple file
> > > descriptors, waiting until... it is possible to perform... I/O operation
> > > (e.g., read(2)) without blocking".
> >
> > These are not atomic operations. At the time of select() defice may be
> > indeed ready, but at read() not anymore.
> I'm not familiar with the device specifics, but if this is not a bug, I
> would consider this a non-optimal design decision, since it defeats the
> whole sense of select(2).

I disagree. Look at the following scenario:
1. Device is ready to write
2. Device writes
3. Program is doing select()
4. select() returns > 0
5. Device gets disconnected and the kernel discards all information
regarding the device
6. Program is doing read()
7. read() fails

You may of course argue, that you should keep the information the
device sent in some buffer. But how long? Who could discard it? What
if device reconnects before someone reads the buffer?

> Drivers usually read the data from the hardware in an interrupt or
> polling routine and signal to select(2) that the data is available. You
> use select(2) to be sure that read(2) doesn't block.

You use select() to check if there is data to be read. Not that read()
doesn't block.

> read(2) usually returns the data already read.

I don't know what you mean here.

> Alternatively, if you have 1. a flag in a status register that data is
> available in the hardware, and 2. good reasons to read from the hardware
> in read(2), you may do that, too. Should the device be not ready at that
> moment, you can return something like EIO instead of sleeping.

Keep in mind that select(); read() sequence is not atomic and many
things can happen to the hardware in the mean time.

> If the official driver documentation or source code doesn't explicitly
> state that the driver may block in read(2) after a successful select(2),
> I would still ask the driver maintainers about that; chances are this
> behavior is not what they had in mind, and they are just not aware of
> it.

I disagree. As said above successful select() does not mean read()
will not block. To make read() not block you need to set the file
descriptor to non blocking mode. And that's the only way that
guarantees read() not to block.

> > I got "Operation now in progress" from connect() in bluetooth case.
> If you use non-blocking I/O, you should not call read(2) just after
> connect(2). You have to select(2) on the socket for writing. When
> select(2) reports that the socket is available for writing, you should
> check it for errors. If there are no errors, you may select(2) for
> reading.

Why? It doesn't make sense for me...

And it was connect() that returned an error. Not read() or select().

> If you don't do this, read(2) may sometimes work and sometimes fail,
> depending on the connection state at that moment. Judging from your last
> postings, this may well be the case.

Any rationale for this claim? And fail or hang?

> IIRC, this technique is described in Rochkind. It requires some
> additional state variables, and it will most probably affect your main
> loop since you detect a possible failure later than you would with
> blocking.

Haven't look into Rochkind for a long time. Will do this :) Thanks for the hint.

take care,
Pawel Kot

reply via email to

[Prev in Thread] Current Thread [Next in Thread]