RE: UDP recvmsg blocks after select(), 2.6 bug?

David Schwartz
2004-10-09T18:28:35Z

> [...]
> > Where, specifically, does the standard guarantee that a
> > subsequent call to
> > 'recvmsg' will not block?
>
> When using select() on a socket for reading, select will block until
> that socket is ready.
>
> According to POSIX:
>
> A descriptor shall be considered ready for reading when a call to an
> input function with O_NONBLOCK clear would not block, whether or not
> the function would transfer data successfully.

Note that it says *would* not block, not *will* not block. The definition
of the word "would" is "an expression of probability or likelihood" (or a
"presumption or expectation"). This is *not* a guarantee.

> and
>
> If a descriptor refers to a socket, the implied input function is the
> recvmsg() function with parameters requesting normal and ancillary data,
> such that the presence of either type shall cause the socket to
> be marked
> as readable. The presence of out-of-band data shall be checked if the
> socket option SO_OOBINLINE has been enabled, as out-of-band data is
> enqueued with normal data. If the socket is currently listening, then it
> shall be marked as readable if an incoming connection request has been
> received, and a call to the accept() function shall complete without
> blocking.
>
> Thus recvmsg() shouldn't in any case block after a select() on a socket.

I don't draw that conclusion from that paragraph. It does say the presence
of normal data shall mark the socket readable, but it doesn't require the
kernel to keep that data available, at least not as far as I can see.

As far as I can tell, neither of these two excerpts prohibit an
implementation from, for example, discarding UDP data (say, to save memory)
after it triggered a read hit on a 'select' call. Yes, the 'recvmsg' call
would not have blocked, had it been made at the time the data was available.

DS