Releases: neosmart/rsevents
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).
AutoResetEventandManualResetEventare now implemented as two-bit mutexes
on top of theparking_lot_corecrate/futex abstraction. This results in much
more complicated logic inrseventsitself 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
Awaitabletrait has been extended with associated typeAwaitable::T,
which is the result of a successfulAwaitable::wait()call, allowing
Awaitableto be used as an abstraction for any type that yields an object or
instance of a type as a result of a wait operation. Awaitableis also extended with associated typeAwaitable::Error
implementingAwaitableError, which is the result of a bounded wait call like
Awaitable::wait_for(Duration)orAwaitable::wait0(), with its own
associated typeAwaitableError::UnboundedError, which specifies the
(possibly different) error type for unbounded waits viaAwaitable::wait()
(which blocks indefinitely until theAwaitabletype yields).- These changes to
Awaitablemake it possible to useAwaitableas an
abstraction for non-event synchronization objects, like std's ownMutex,
which return aResult<,>that isn'tResult<(), TimeoutError>. - Despite all these changes,
Awaitableremains backwards-compatible and
exposes the same error-free,bool-returningwait(),wait_for(), and
wait0()methods by special-casing situations where
AwaitableError::UnboundedError = ()(as is the case withManualResetEvent
andAutoResetEvent) to unlock access to the old wait functions with their
boolean-denominated return types. - The type
TimeoutErrorhas been introduced as the defaultAwaitableError
forManualResetEvent,AutoResetEvent, and any otherAwaitabletypes that
offer infallible wait operations (with a timeout being the only possible
error). - Downstream crates using the
Awaitabletrait to provide their own
synchronization objects need to modify their implementations to implement
Awaitable::try_xxx()instead ofAwaitable::xxx()- for all existing cases,
this is just a straight-forward rename, plus defininingAwaitable::T = ();
andAwaitable::Error = TimeoutError;(if rust's default associated types
feature were complete and available, not even that would be necessary). - The
Awaitabletrait now providesAwaitable::wait0()by default; for cases
where there is no faster alternative toAwaitable::wait_for(Duration::ZERO)
– types that can provide a faster (and preferably lock-free/wait-free)
alternative are encouraged to overrideAwaitable::try_wait0()(there is no
need to overrideAwaitable::wait0()itself as it is routed viatry_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).
AutoResetEventandManualResetEventare now implemented as two-bit mutexes
on top of theparking_lot_corecrate/futex abstraction. This results in much
more complicated logic inrseventsitself 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
Awaitabletrait has been extended with associated typeAwaitable::T,
which is the result of a successfulAwaitable::wait()call, allowing
Awaitableto be used as an abstraction for any type that yields an object or
instance of a type as a result of a wait operation. Awaitableis also extended with associated typeAwaitable::Error
implementingAwaitableError, which is the result of a bounded wait call like
Awaitable::wait_for(Duration)orAwaitable::wait0(), with its own
associated typeAwaitableError::UnboundedError, which specifies the
(possibly different) error type for unbounded waits viaAwaitable::wait()
(which blocks indefinitely until theAwaitabletype yields).- These changes to
Awaitablemake it possible to useAwaitableas an
abstraction for non-event synchronization objects, like std's ownMutex,
which return aResult<,>that isn'tResult<(), TimeoutError>. - Despite all these changes,
Awaitableremains backwards-compatible and
exposes the same error-free,bool-returningwait(),wait_for(), and
wait0()methods by special-casing situations where
AwaitableError::UnboundedError = ()(as is the case withManualResetEvent
andAutoResetEvent) to unlock access to the old wait functions with their
boolean-denominated return types. - The type
TimeoutErrorhas been introduced as the defaultAwaitableError
forManualResetEvent,AutoResetEvent, and any otherAwaitabletypes that
offer infallible wait operations (with a timeout being the only possible
error). - Downstream crates using the
Awaitabletrait to provide their own
synchronization objects need to modify their implementations to implement
Awaitable::try_xxx()instead ofAwaitable::xxx()- for all existing cases,
this is just a straight-forward rename, plus defininingAwaitable::T = ();
andAwaitable::Error = TimeoutError;(if rust's default associated types
feature were complete and available, not even that would be necessary). - The
Awaitabletrait now providesAwaitable::wait0()by default; for cases
where there is no faster alternative toAwaitable::wait_for(Duration::ZERO)
– types that can provide a faster (and preferably lock-free/wait-free)
alternative are encouraged to overrideAwaitable::try_wait0()(there is no
need to overrideAwaitable::wait0()itself as it is routed viatry_wait0()
where it exists.