Search code examples
windowssocketsiocp

Is there any way to use IOCP to notify when a socket is readable / writeable?


I'm looking for some way to get a signal on an I/O completion port when a socket becomes readable/writeable (i.e. the next send/recv will complete immediately). Basically I want an overlapped version of WSASelect.

(Yes, I know that for many applications, this is unnecessary, and you can just keep issuing overlapped send calls. But in other applications you want to delay generating the message to send until the last moment possible, as discussed e.g. here. In these cases it's useful to do (a) wait for socket to be writeable, (b) generate the next message, (c) send the next message.)

So far the best solution I've been able to come up with is to spawn a thread just to call select and then PostQueuedCompletionStatus, which is awful and not particularly scalable... is there any better way?


Solution

  • It turns out that this is possible!

    Basically the trick is:

    • Use the WSAIoctl SIO_BASE_HANDLE to peek through any "layered service providers"
    • Use DeviceIoControl to submit an AFD_POLL request for the base handle, to the AFD driver (this is what select does internally)

    There are many, many complications that are probably worth understanding, but at the end of the day the above should just work in practice. This is supposed to be a private API, but libuv uses it, and MS's compatibility policies mean that they will never break libuv, so you're fine. For details, read the thread starting from this message: https://github.com/python-trio/trio/issues/52#issuecomment-424591743