Urgent need for advice: POLLHUP and sockets

Ove Kaaven ovek at arcticnet.no
Tue Apr 16 16:47:59 CDT 2002


On Tue, 16 Apr 2002, Martin Wilck wrote:

> please consider the following problem:

Sounds like one we've discussed and resolved before.

> On sockets, when POLLHUP is received, it is perfectly legitimate to
> continue reading data until a read() or recv() call returns 0 bytes.

Yes, it's still valid to read, but no more data will arrive on the socket,
so the only thing you'll read is data that's already waiting in the kernel
buffers. There's no reason to continue actively polling.

> The current wine implementation calls set_select_events( &sock->obj, -1 )
> when POLLHUP or POLLERR is received, disabling any future events from the
> socket.

Yes. POLLHUP cannot be masked out, so letting the socket continue to be
polled results in a busy-wait and 100% CPU usage.

> However, if an application uses asynchronous IO (or only asynchronous
> notification via WSAAsyncSelect() or WSAEventSelect()), this also inhibits
> reception of POLLIN events which can perfectly well occur if there are
> still unread data in the kernel buffers. Thus the app will never notice
> that there is still data to be read.

Not quite. No more data will arrive on the socket when it's in POLLHUP
state, so there's no need for the server to poll. Instead, it notifies the
app that there's still data remaining to be read next time it reads from
the socket (this is what the "check whether condition is satisfied
already" case in sock_reselect does, it explicitly does a poll even if the
socket is removed from the main polling loop, in order to check for
remaining data). Sending the app new FD_READ events only after it has read
old data is a documented Windows feature; further FD_READ events are held
back until the app reads old data, and this is what the wineserver
implements, especially in the POLLHUP case.

> A minor point is that sock_poll_event() also sets a FD_CLOSE event
> (if present) everytime it is called with POLLHUP set, effectively
> preventing any APC from being called, at least if the app waits for
> FD_CLOSE and asynchronous send/recv operations at the same time (likely).
> This can be worked around by setting FD_CLOSE only once and then blocking
> it, although I am not sure if that is correct behaviour (permanently
> signalling FD_CLOSE is obviously incorrect).

The FD_CLOSE is only sent when there's no remaining data to be read
(POLLIN is not present in the result of poll). It should not be a problem
since the set_select_events( &sock->obj, -1 ) removes the socket from the
main poll loop, so no further FD_CLOSEs would be sent.




More information about the wine-devel mailing list