digitalmars.D - Re: zero-copy API
- Sean Kelly <sean invisibleduck.org> Oct 15 2010
Denis Koroskin Wrote:On Fri, 15 Oct 2010 08:03:21 +0400, Sean Kelly <sean invisibleduck.org> wrote:Perhaps not terribly relevant, but IOCP on Windows does this. To perform an asynchronous read you supply the buffer to recv and then an event is signaled when the read completes. The same API works for file io and there's support for scatter/gather as well. It makes for a more complicated program though.
We are using IOCP for a game server with a great success. I'm not even sure we could achieve the same level of latency if we were using Linux and epoll. I've implemented a Stream API (FileStream and SocketStream) on top of IOCP (both sync and async), and it doesn't complicate a program when used right. Automatic thread pooling for event callbacks is very handy, and since events for the same socket don't overlap you don't even need to synchronize anything but global state (in which case a simple ReadWriteMutex is more than enough). Unfortunately, I'm not sure how to integrate that concept into D2 design. Even though events don't overlap, the callback thread is always different and as such thread local variables are unaccessible. I was thinking about dynamic thread local variables switching, but Walter says it is either highly inefficient or impossible to to implement.
I've considered moving TLS into Fibers using the library-based OSX design. With that approach, you'd perform the read and then yield(), so programming would be as if you were writing plain old blocking sockets code. The obvious drawback is that library-based TLS is far less optimal than using the built-in method. Regarding IOCP, one thing I don't terribly like about it is that you have to preallocate a buffer for every IO operation you want to have pending. I guess the rationale is that it replaces the system buffer so things kind of even out, but I do like the option of simply having a static buffer used for reads with the *nix methid (poll, etc).
Oct 15 2010