Comment by tarruda

1 hour ago

> especially with the new IO mechanism which allows supper efficient code that looks good whether it's implemented single-threaded, multi-threaded or just via an event loop!

I had some trouble understanding how the async/await mechanism works:

  var foo_future = io.async(foo, .{args});
  defer if (foo_future.cancel(io)) |resource| resource.deinit() else |_| {}

  var bar_future = io.async(bar, .{args});
  defer if (bar_future.cancel(io)) |resource| resource.deinit() else |_| {}

  const foo_result = try foo_future.await(io);
  const bar_result = try bar_future.await(io);

My assumption is that calling io.async using an event loop implementation of IO, it will internally start a "task" (or whatever it should be called) and that the future is a handle to it. So far so good.

The part that I don't understand is what happens when you call future.await(io). Will the IO implementation somehow suspend the current function and resume once the future is resolved? If so, does that mean that every function in zig is a stackless coroutine?

> If so, does that mean that every function in zig is a stackless coroutine?

No and yes.

If you're using Io.Threaded, then the concurrency model is multithreading and calling Future.await will block your thread on a OS futex.

If you're using Io.Evented, then the concurrency model is green threads / fibers and calling Future.await will suspend the current green thread by yielding (swapping CPU state with another fiber).

Zig currently does not support stackless coroutines so today you can't have that, but we used to have them (pre self-hosted compiler), and there's an accepted proposal to bring them back, in which case any function that calls await, or that otherwise has a suspension point, would have to be transformed into a stackless coroutine by the compiler, yes. The plan is for that to happen transparently without requiring an `async` annotation in the function signature, like we already did in the past.

This is an old post of mine that explains how that worked at a high level: https://kristoff.it/blog/zig-colorblind-async-await/