On Wed, 17 Apr 2002, Martin Wilck wrote:
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).
Hmm - this code went away with CVS version 1.28 of sock.c. Perhaps we need to reintroduce it somehow.
I can send you the sock.c I have if you wish, but you may be able to check out an earlier revision yourself.
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.
Sorry, I cannot see what you are talking about, not in the current CVS version. All that happens after a read() is issued is _enable_event (FD_READ, 0, 0), and that clears the pending mask for FD_READ. How would that ever be set again, and FD_READ signalled ?
req->mask is here FD_READ, and the handler contains
sock->pmask &= ~req->mask; sock->hmask &= ~req->mask; sock->state |= req->sstate; sock->state &= ~req->cstate; sock_reselect( sock );
where sock_reselect includes this at the end
/* check whether condition is satisfied already */ pfd.fd = sock->obj.fd; pfd.events = ev; pfd.revents = 0; poll( &pfd, 1, 0 ); if (pfd.revents) sock_poll_event( &sock->obj, pfd.revents);
result: sock_poll_event sets FD_READ flag and notifies the application in response to the _enable_event, i.e. after it has read something, even if the socket is not in the main poll loop. We never got around to change the comment to explain this additional function.
The key probably is that sock_poll_event() was called from sock_reselect() if the "condition is satisfied", which is no longer the case in 1.28.
If this code path was removed, then you'll probably have to put it back in.