[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: nonblocking read
Re: nonblocking read
Mon, 12 Nov 2007 23:33:50 +0100
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).
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. read(2) usually
returns the data already read.
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.
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
> 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
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.
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
With kind regards,