We wrote software that leverages I/O Completion Ports, and uses WSASend on SOCKET objects, WriteFile on named pipes.
In both situations we are finding that those APIs return SOCKET_ERROR / WAS_IO_PENDING [1] a lot sooner than we expected (or the equivalent for a named pipe WriteFile operation).
It seems we have wrongly assumed that asynchronous completion would trigger if we fill up the send buffer (nInBufferSize in CreateNamedPipe), instead it seems to be a lot more aggressive and unrelated to the size of the send buffer. For both sockets and named pipes, a large send buffer (100k+) and small messages (a few bytes) will always be completed asynchronously on the second write if done fast enough.
Can anyone confirm this? Does anyone have information on the heuristics that the Windows implementation follows in deciding when to complete I/O operations asynchronously, versus doing a synchronous completion?
[1] "If the overlapped operation is successfully initiated and will complete later, WSASend returns SOCKET_ERROR and indicates error code WSA_IO_PENDING." - http://msdn.microsoft.com/en-us/library/windows/desktop/ms742203(v=vs.85).aspx
Why do you think you need to know or care. It's not a documented part of the API and it's possibly affected by the drivers and any layered service providers in the stack at the time.
You have to write the correct code to handle either a successful 'synchronous' send or a pending 'asynchronous' send so what difference does it make how often you get either kind of result?
Also, unless you are using SetFileCompletionNotificationModes() to enable
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
the same code path is used for both sync and pending results.