Description
Overview
Currently, Mio currently only supports Linux and Darwin platforms (though *BSD support could happen relatively easily). It uses epoll and kqueue respectively to provide a readiness API to consumers. Windows offers a completion based API (completion ports) which is significantly different from epoll & kqueue. The goal would be to tweak Mio in order to support Windows while still maintaining low overhead that mio strives for across all platforms.
History
I have wavered a bunch on the topic of how to best support Windows. At first, I had originally planned to do whatever was needed to support windows even if the implementation was less than ideal. Then, started towards not supporting windows with Mio and instead provide a standalone IO library that supported windows only. I started investigating the IOCP APIs in more depth and thinking about what a windows library would look like and it was very similar to what mio already is.
Completion Ports
There are a number of details related to using completion ports, but what matters is that instead of being notified when an operation (read
, write
, accept
, ...) is ready to be performed and then performing the operation, an operation is submitted and then completion is signaled by reading from a queue.
For example, when reading, a byte buffer is provided to the operating system. The operating system then takes ownership of the buffer until the operation completes. When the operation completes, the application is notified by reading off of the completion status queue
Strategy
The strategy would be to, on windows, internally manage a pool of buffers. When a socket is registered with the event loop with readable interest, a read a system read would be initiated supplying an available buffer. When the read completes, the internal buffer is now full. The the event loop would notify readiness and the user will then be able to read from the socket. The read would copy data from the internal buffer to the user's buffer and the read would be complete.
On write, the user's data would be copied to a an internal buffer immediately and then the internal buffer submitted to the OS for the system write call.
Mio API changes
In order to implement the above strategy, Mio would not be able to rely on IO types from std::net
anymore. As such, I propose to bring back TcpStream
and TcpListener
implemented in mio::net
. Since Mio will then own all IO types, there will be no more need to have the NonBlock wrapper. Also, it seems that
NonBlock` can be confusing (see #154). So, all IO types in mio will always be blocking.
I believe that this will be the only required API change.