I still have problems with FD_CLOSE signalling.
AFAICS FD_CLOSE must be signalled when either of the three following conditions hold:
1 Network error (Linux signals POLLERR) 2 Graceful close by the peer (Linux signals POLLHUP) 3 shutdown (SD_SEND) by the peer (Linux signals POLLIN with 0 bytes to read).
** Condition 3 will only be noticed if we tell poll() we're interested ** ** in POLLIN. **
In that case, if 1 or 2 occurs, POLLIN will also be signalled, whether or not there are still data to be read.
However, we cannot simply activate POLLIN always, because if there _is_ data to be read on a normal connection and the app does not read it immediately, the server would busy-loop.
We can take advantage of the fact that after every recv(), winsock will notify the server and try to re-enable FD_READ. (This does not hold for ReadFile() operations, as I pointed out in my recent "RFC..." posting).
Thus what we could do is enable polling for POLLIN whenever FD_READ is re-enabled, even if then app has not registered for FD_READ notification, and disable it when POLLIN is received. Furthermore, finishing an asynchronous read request would also reenable POLLIN, whether or not there are more requests in read queue. Only an app that uses synchronous ReadFile() calls would never see FD_CLOSE.
Does that seem correct, or am I again overlooking something??
It is a completely different story _at what time_ FD_CLOSE should be signalled when one ove the above 3 conditions is actually encountered. The Winsock2 spec says different things:
In docs of WSAEventSelect: "FD_CLOSE should only be posted after all data is read from a socket, but an application should check for remaining data upon receipt of FD_CLOSE to avoid any possibility of losing data".
This suggests that we could signal FD_CLOSE if POLLHUP is received, even if there is still data to be read, although we "should" not.
In docs of WSAAsyncSelect: "[FD_CLOSE is posted] after remote system initiated graceful close, when no data currently available to receive (note: if data has been received and is waiting to be read when the remote system initiates a graceful close, the FD_CLOSE is not delivered until all pending data has been read)"
This suggests the opposite - signal FD_CLOSE only after the app has read all data, even if this is far later than the actual POLLHUP. Actually this suggests that FD_CLOSE is _equivalent_ with condition 3 above, regardless if 1 or 2 are in effect.
This is the behaviour I have tried to implement in my latest patches.
Again, am I overlooking something?
Martin