Hi all,
please consider the following problem:
On sockets, when POLLHUP is received, it is perfectly legitimate to continue reading data until a read() or recv() call returns 0 bytes.
The current wine implementation calls set_select_events( &sock->obj, -1 ) when POLLHUP or POLLERR is received, disabling any future events from the socket.
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.
My first reaction to this was to comment out the above call to set_select_events() and continue listening to events from the socket. However, due to the semantics of poll(), this will cause a POLLHUP event on this socket for each and every iteration of the wineserver's main select loop, putting the server basically into a busy-wait state.
How can this be resolved? We seem to have the choice between
a) busy loop in the server (bad) b) discarding data which could be legitimately read by the application (very bad).
Any hints/comments/ideas?
Please note that it is insufficient to queue all pending APCs on the socket when POLLHUP is received, because the app may very well queue some _after_ the close event arrives.
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).
I hope someone has a good idea how to resolve this, Martin