Page 2 of 2

Re: Open source Midori?

Posted: Wed Nov 25, 2015 11:42 am
by dschatz
Brendan wrote: For legacy non-blocking code, I think you'd just do something like (e.g.) "fp = await Async.Open(filename);".
I assume you mean "legacy blocking code" here. This won't work - The await will cause an (early) return with a Future<ReturnTypeOfFunction>. You need some blocking way to turn a Future<T> into a T - a mechanism they do not provide. Await is just syntactic sugar for locally creating a continuation. As I discussed earlier, this is insufficient for support legacy code because it needs to be done on every function in the call path.

To make this concrete consider the implementation of a blocking read:

Code: Select all

ssize_t read(int fd, void *buf, size_t count)
and I am provided the following non-blocking interface from the system:

Code: Select all

Future<ssize_t> async_read(int fd, void *buf, size_t count)
Don't worry about the particulars of the interface here. Suffice it to say, the read is complete when the returned future resolves. If I implement the blocking read as follows:

Code: Select all

ssize_t read(int fd, void *buf, size_t count) { return await async_read(fd, buf, count); }
Then it would be a compiler bug, my return type is not a Future and so await cannot be used.

Re: Open source Midori?

Posted: Wed Nov 25, 2015 1:50 pm
by SpyderTL
The only option would be to wrap the synchronous read() method in an asynchronous readAsync(), which calls read() on a separate thread. Then you could "resume" the rest of your code on the new thread, assuming you copy all of your thread context (variables/stack/etc.) to the new thread...

Not really an ideal solution, but probably the least impact to existing code.

Re: Open source Midori?

Posted: Wed Nov 25, 2015 3:16 pm
by Rusky
Brendan wrote:When Midori's developers say "everything is non-blocking" what they really mean is that waiting for a message to arrive is the only thing that causes a thread to block; and because everything waits for messages to arrive everything is blocking. ;)
This is false. What they really mean is that all APIs that would normally block return a Future<T> instead of blocking, and your code continues to run. This includes waiting for messages- you just get a Future<Message>.

There is no Future.get() call, either- the only way to use such a value is to hand it a continuation that takes the value as an argument, at which point it hands you back a new Future for the result of that continuation. Your code still continues to run.

You are right that `await` is syntactic sugar, but it's not quite the same as syntactic sugar for blocking. It's syntactic sugar for packaging up the rest of the function into a continuation, handing that continuation to a future, and then returning the future you get back. While the function containing `await` appears to block, the thread does not- and your caller continues to run.
Brendan wrote:For legacy non-blocking code, I think you'd just do something like (e.g.) "fp = await Async.Open(filename);".
Like dschatz said, this will not work- it will just change the return type of your function to a Future. You can't just run legacy code with a shim library that hides all the async stuff. However, `await` does make it easier to port legacy code. This is necessary anyway for Midori, because it only supports its own C#-derived programming language that no legacy software is written in to begin with.