Hi Daniel,
I have some concerns wrt your WSAAccept implementation you sent to wine-patches on Sunday. I have thought a bit about this function (did you notice my preliminary implementation on Nov. 7 (subject "[EXPERIMENTAL PATCH]: Winsock2" ?).
The problem I see is related to the treatment of the peer when the user-supplied condition function returns CF_REJECT or CF_DEFER.
Your implementation calls WS_Accept _before_ calling the condition function. That is, the peer will think its connection request was accepted, and possibly start to send or poll for data. Then if the Condition function returns CF_REJECT, the connection is closed.
Even worse, for CF_DEFER, the peer receives nothing, the new socket cs returned by WS_Accept remains open but is forgotten after WSAAccept() returns (correct me if I'm wrong). So the peer will think it's connected, but no future WSAAccept or WS_Accept call will ever return a socket connected to it, and it'll be sending data into the void.
I think you must at least closesocket(cs) for CS_DEFER as well to avoid this situation. Alternatively (that's the way I did it) the new socket can be stored in the wineserver to be returned by future WSAAccept calls.
The Winsock2 specs say that "[WSAAccept] extracts the first connection on the queue of pending connections" (after a CF_DEFER, that should be the previously deferred connection, until it's either accepted or rejected). Moreover, it says that "[In the CF_DEFER case] no action about this connection request should be taken by the service provider". Taken seriously, this means that it's wrong to call accept() on this request before a positive decision was made by the Condition function.
Summarizing, the peer should see:
CF_ACCEPT: his request is accepted (this case is OK). CF_REJECT: his request is rejected (not ok, he receives an accept followed by a close). CF_DEFER: nothing (not OK, he receives an accept followed by ???)
I have no idea how this affects behaviour of "real" applications.
The essential problem is that there is no way (well, I have found none) to obtain the peer's socket address on Linux without accept()ing first. I guess that is what made you call accept() before the condition routine. Perhaps someone can come up with a method to read the socket address of a waiting connection request before it's accepted, but my guess is this won't work without a kernel hack.
At the very least, though, I consider it necessary to include a FIXME that tells users that this function may behave different from what the specs say.
Please don't get me wrong, it's great to see other people work on Winsock, and your code is clean. I just thought I need to express these concerns.
Regards, Martin