It can be useful for tests to be able to run an event loop without
having to depend on eio_main.
Also, replace the inefficient list-based queue with a proper Lf_queue.
In "Object Capabilities", people frequently assume "object" is referring
to the use of OCaml objects (i.e. polymorphic records).
Also, link to rational document when discussing provider interfaces.
Lwt needs this because it uses promises for thread results, and threads can always raise.
But we don't use promises for that, and so can afford to be more explicit.
- A promise is now simply unresolved or resolved.
- `Promise.fulfill` is now `Promise.resolve`.
- `Promise.break` and `Promise.broken` are gone.
- `Promise.await` doesn't raise; `await_result` is gone.
- `Promise.state` is now `Promise.peek` and returns an option.
- `Promise.fulfilled` is now `Promise.create_resolved`.
Some helpers using result types are provided to handle cases that need exceptions:
- `type 'a or_exn = ('a, exn) result t`.
- `resolve_ok` and `resolve_error` wrap the value in `Ok` or `Error`.
- `await_exn` awaits a result promise and raises the error.
Cancellation contexts are now only about making things stop promptly,
not about reporting errors. That's now handled entirely by the switches.
This fixes a problem where an error raised while cancelling an operation
would be lost.
`Switch.turn_off` is now called `Switch.fail`.
Documented how cancellation is supposed to work.
Added `Fibre.check ()`, to check whether the current context has been
cancelled.
In eio_luv, don't wrap an extra Cancelled around cancelled exceptions.
Don't create a `Multiple_exn.T` of a cancellation and something else.
Just ignore the cancellation in that case and report the interesting
exception. Whoever sent the cancellation is responsible for reporting
that problem.
Mark all nested contexts as cancelled before running any functions.
If a function fails (shouldn't happen now), still run those from other
contexts.
Some arguments in favour of this:
- This is the most flexible arrangement (you can add yields gets the
other combinations).
- The order seems a bit more natural (the README examples look better).
- Might be better for the cache in some cases (domainslib works this way).
- Means that `Fibre.both f g` starts `f` and `g` in similar contexts.
Previously, `f` started before any queued items, while `g` started
after, which was a bit inconsistent.
This also adds some documentation about scheduling order to the ocamldoc
(note that the previous documentation for `fork` was wrong) and adds a
`rationale.md` file explaining the choice.
Instead of requiring every cancellable operation to pass a `~sw`
argument, give each fibre a default switch and use that. It's too easy
to forget to make something cancellable and clutters up the code.
- Set up a box so that wrapping works correctly.
- Print a `+` at the start of each trace line to show it is trace output.
- Format location tag with the rest of the output (fixes wrapping).
- Add tests for traceln.