Search code examples
socketswinapitcpioiocp

Could ConnectEx with SetFileCompletionNotificationModes return synchronously?


In the MSDN page of the ConnectEx() API, there is nothing about SetFileCompletionNotificationModes() and about if setting the flag FILE_SKIP_COMPLETION_PORT_ON_SUCCESS will work also with ConnectEx().

The MSDN page of SetFileCompletionNotificationModes() clearly states that if the flag FILE_SKIP_COMPLETION_PORT_ON_SUCCESS is set, then all (all ?) APIs that should return ERROR_IO_PENDING may return immediately, without queueing the OVERLAPPED in the IOCP loop.

So, my question is: Does this really apply to ALL of the APIs which takes an OVERLAPPED and that return ERROR_IO_PENDING?

I set my socket as FILE_SKIP_COMPLETION_PORT_ON_SUCCESS before connecting the socket by calling ConnectEx().

Should I expect an immediate return by ConnectEx() (that is, it doesn't return ERROR_IO_PENDING and the I/O completion will be totally skipped by the IOCP loop, e.g. maybe when the connection is to localhost)?

Even if I just set FILE_SKIP_COMPLETION_PORT_ON_SUCCESS after ConnectEx() successfully completed, (e.g. I set that in the IOCP completion routine of ConnectEx()), if I disconnect and reuse that socket for a new connection by calling ConnectEx() again, it will be like I set that flag before ConnectEx(), so the same question arise.


Solution

  • Why do you care? Assuming that it can't will just mean that you need to have a special case for this one API call. Assuming it can will mean that the code that calls ConnectEx() should look just like the code that calls all the other overlapped APIs, WSARecv(), WSASend(), etc. Also given the nature of the existing documentation you SHOULD assume that it can. Therefore, it's correct to write the code that doesn't have the special case...

    I would expect that in most situations with a real networking stack it's unlikely that you'd ever get a sync return from ConnectEx(), however, if you were to install some kind of custom diagnostic Winsock provider which simply mocked out connections for you, or if someone invents a network layer which can connect very quickly then it may be possible.

    In my opinion you don't need to know the answer to this question, you just need to write the code that should be written given the documentation (which says it could complete synchronously) and the fact that it's probably the code that people would expect you to have written anyway if they'd looked at any of your other code that calls other overlapped APIs.