As I've continued to play with my async IO stuff, I've found that the programs do get a bit hard to read and maintain. You got handlers here and handlers there, and the flow between them is not easy to disentangle at first.

As I've continued to play with my async IO stuff, I've found that the programs do get a bit hard to read and maintain. You got handlers here and handlers there, and the flow between them is not easy to disentangle at first.

So I got inspired by Boost.Coroutine, which on Windows uses fibers to make "async look sync". The idea is you can have your cake and eat it: you get the benefits of async IO, while being able to write code which looks synchronous.

I just whipped this up in a couple of hours, so naming and implementation could probably do with a bit more polish, but here's the core result:

  inputStream := NewAsyncFileStream(Service, InputFilename, fcOpenExisting, faRead, fsRead);

  serviceContext := NewIOServiceCoroutineContext(Service);
  future := NewIOFuture(serviceContext);

  // queue the async read
  // this will return once the read has completed
  bytesRead := AsyncRead(inputStream, FBuffer, TransferAll(), future);

    if (not future.Result.Success) and (future.Result <> SystemResults.EndOfFile) then
  begin
      future.Result.RaiseException('Reading file');
  end;


So instead of passing a completion handler when performing an async operation, you pass a future. 

This future will switch to a fiber which just runs the IOService, that is waits for IO completion packets and executes the associated handlers.

When a "future completion handler" is executed it switches back to the fiber associated with the future (ie which made the async call) so that the calling code resumes as if the call was synchronous.

Here's the core of the file copy example: http://paste.ie/view/f0f6b7f2

For reference here's core of the old version using completion handlers: http://paste.ie/view/5d173758

Will brush it up and push it to the repo soon, along with TLS support (https, yeah baby yeah!).
http://paste.ie/view/f0f6b7f2

Comments

  1. Javier Hernández schannel?! Really? But can you set Ciphers/CipherSuites/Hashes/KeyExchangeAlgorithms/Protocols/Renego* settings in  HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL correctly and didn't screw your https connections? Frankly, I couldn't and had to reset all the settings. Thanks to IISCrypto tool you can manage these settings, but you always end up with some https site or RDP connection error without visual indication that your settings are wrong. And you know what? You can always open this same https site (ha! ironically https://www.microsoft.com/security/portal/mmpc/default.aspx ) in Chrome without a hitch!
    What do you like in schannel?

    ReplyDelete
  2. Javier Hernández I've made a wrapper to mbedTLS, but should hopefully be generic enough for others (I've kept OpenSSL in mind simply because it's so widespread).

    ReplyDelete
  3. Javier Hernández I had a quick look and I think SChannel should map cleanly to my TLS interface. Seems worthwhile to add SChannel as a provider as well.

    ReplyDelete
  4. Javier Hernández Sure, like I said, just have to clean it up a bit :)

    ReplyDelete
  5. Javier Hernández Thanks for the pointer, hadn't noticed those. Should be able to leverage it via IOCP if needed.

    ReplyDelete
  6. Javier Hernández I've looked into HTTP/2. It's a non-trivial protocol to say the least. But I might take a stab, if I have sufficient time.

    ReplyDelete
  7. Javier Hernández Yeah, I was thinking about integrating one of those, given the complexities of the protocol and the risk of bugs etc.

    ReplyDelete

Post a Comment