Tags: neosmart/rsevents
Tags
rsevents 0.3.1 rsevents 0.3.x is a complete behind-the-scenes rewrite of the events primitives to unlock additional performance gains and further reduce the cost of signalling events. The consumer-side API (as exposed via the `Awaitable` trait) remains backwards compatible, although the `Awaitable` trait itself has been supercharged to support fallible waits (where waiting on an event can generate an error other than just a timeout) and awaitable results (where awaiting non-event `Awaitable` impls can return something other than just the `()` void type). Only users implementing their own custom `Awaitable` types need to make any changes to their code to upgrade from `rsevents` version `0.2.x` to `0.3.x` – and the changes are minimal at that (read on). * `AutoResetEvent` and `ManualResetEvent` are now implemented as two-bit mutexes on top of the `parking_lot_core` crate/futex abstraction. This results in much more complicated logic in `rsevents` itself to correctly handle race conditions between setting and awaiting an event, but allows setting, resetting, and awaiting/obtaining events to be wait-free and lock-free in the case of no contention. * The `Awaitable` trait has been extended with associated type `Awaitable::T`, which is the result of a successful `Awaitable::wait()` call, allowing `Awaitable` to be used as an abstraction for any type that yields an object or instance of a type as a result of a wait operation. * `Awaitable` is also extended with associated type `Awaitable::Error` implementing `AwaitableError`, which is the result of a bounded wait call like `Awaitable::wait_for(Duration)` or `Awaitable::wait0()`, with its own associated type `AwaitableError::UnboundedError`, which specifies the (possibly different) error type for unbounded waits via `Awaitable::wait()` (which blocks indefinitely until the `Awaitable` type yields). * These changes to `Awaitable` make it possible to use `Awaitable` as an abstraction for non-event synchronization objects, like std's own `Mutex`, which return a `Result<,>` that isn't `Result<(), TimeoutError>`. * Despite all these changes, `Awaitable` remains backwards-compatible and exposes the same error-free, `bool`-returning `wait()`, `wait_for()`, and `wait0()` methods by special-casing situations where `AwaitableError::UnboundedError = ()` (as is the case with `ManualResetEvent` and `AutoResetEvent`) to unlock access to the old wait functions with their boolean-denominated return types. * The type `TimeoutError` has been introduced as the default `AwaitableError` for `ManualResetEvent`, `AutoResetEvent`, and any other `Awaitable` types that offer infallible wait operations (with a timeout being the only possible error). * Downstream crates using the `Awaitable` trait to provide their own synchronization objects need to modify their implementations to implement `Awaitable::try_xxx()` instead of `Awaitable::xxx()` - for all existing cases, this is just a straight-forward rename, plus definining `Awaitable::T = ();` and `Awaitable::Error = TimeoutError;` (if rust's default associated types feature were complete and available, not even that would be necessary). * The `Awaitable` trait now provides `Awaitable::wait0()` by default; for cases where there is no faster alternative to `Awaitable::wait_for(Duration::ZERO)` – types that can provide a faster (and preferably lock-free/wait-free) alternative are encouraged to override `Awaitable::try_wait0()` (there is no need to override `Awaitable::wait0()` itself as it is routed via `try_wait0()` where it exists. rsevents 0.3.0 was yanked in favor of the just-published 0.3.1, as it turns out the overhauled `Awaitable` trait was not sufficiently generic (it was missing a lifetime) as to enable returning non-static instances of `Awaitable::T`, which was a scenario that the 0.3.x releases were meant to support.
rsevents 0.3.0 rsevents 0.3.0 is a complete behind-the-scenes rewrite of the events primitives to unlock additional performance gains and further reduce the cost of signalling events. The consumer-side API (as exposed via the `Awaitable` trait) remains backwards compatible, although the `Awaitable` trait itself has been supercharged to support fallible waits (where waiting on an event can generate an error other than just a timeout) and awaitable results (where awaiting non-event `Awaitable` impls can return something other than just the `()` void type). Only users implementing their own custom `Awaitable` types need to make any changes to their code to upgrade from `rsevents` version `0.2.x` to `0.3.x` – and the changes are minimal at that (read on). * `AutoResetEvent` and `ManualResetEvent` are now implemented as two-bit mutexes on top of the `parking_lot_core` crate/futex abstraction. This results in much more complicated logic in `rsevents` itself to correctly handle race conditions between setting and awaiting an event, but allows setting, resetting, and awaiting/obtaining events to be wait-free and lock-free in the case of no contention. * The `Awaitable` trait has been extended with associated type `Awaitable::T`, which is the result of a successful `Awaitable::wait()` call, allowing `Awaitable` to be used as an abstraction for any type that yields an object or instance of a type as a result of a wait operation. * `Awaitable` is also extended with associated type `Awaitable::Error` implementing `AwaitableError`, which is the result of a bounded wait call like `Awaitable::wait_for(Duration)` or `Awaitable::wait0()`, with its own associated type `AwaitableError::UnboundedError`, which specifies the (possibly different) error type for unbounded waits via `Awaitable::wait()` (which blocks indefinitely until the `Awaitable` type yields). * These changes to `Awaitable` make it possible to use `Awaitable` as an abstraction for non-event synchronization objects, like std's own `Mutex`, which return a `Result<,>` that isn't `Result<(), TimeoutError>`. * Despite all these changes, `Awaitable` remains backwards-compatible and exposes the same error-free, `bool`-returning `wait()`, `wait_for()`, and `wait0()` methods by special-casing situations where `AwaitableError::UnboundedError = ()` (as is the case with `ManualResetEvent` and `AutoResetEvent`) to unlock access to the old wait functions with their boolean-denominated return types. * The type `TimeoutError` has been introduced as the default `AwaitableError` for `ManualResetEvent`, `AutoResetEvent`, and any other `Awaitable` types that offer infallible wait operations (with a timeout being the only possible error). * Downstream crates using the `Awaitable` trait to provide their own synchronization objects need to modify their implementations to implement `Awaitable::try_xxx()` instead of `Awaitable::xxx()` - for all existing cases, this is just a straight-forward rename, plus definining `Awaitable::T = ();` and `Awaitable::Error = TimeoutError;` (if rust's default associated types feature were complete and available, not even that would be necessary). * The `Awaitable` trait now provides `Awaitable::wait0()` by default; for cases where there is no faster alternative to `Awaitable::wait_for(Duration::ZERO)` – types that can provide a faster (and preferably lock-free/wait-free) alternative are encouraged to override `Awaitable::try_wait0()` (there is no need to override `Awaitable::wait0()` itself as it is routed via `try_wait0()` where it exists.