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).
AutoResetEvent
andManualResetEvent
are now implemented as two-bit mutexes
on top of theparking_lot_core
crate/futex abstraction. This results in much
more complicated logic inrsevents
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 typeAwaitable::T
,
which is the result of a successfulAwaitable::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 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 theAwaitable
type yields).- These changes to
Awaitable
make it possible to useAwaitable
as an
abstraction for non-event synchronization objects, like std's ownMutex
,
which return aResult<,>
that isn'tResult<(), TimeoutError>
. - Despite all these changes,
Awaitable
remains 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
TimeoutError
has been introduced as the defaultAwaitableError
forManualResetEvent
,AutoResetEvent
, and any otherAwaitable
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 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
Awaitable
trait 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).
AutoResetEvent
andManualResetEvent
are now implemented as two-bit mutexes
on top of theparking_lot_core
crate/futex abstraction. This results in much
more complicated logic inrsevents
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 typeAwaitable::T
,
which is the result of a successfulAwaitable::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 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 theAwaitable
type yields).- These changes to
Awaitable
make it possible to useAwaitable
as an
abstraction for non-event synchronization objects, like std's ownMutex
,
which return aResult<,>
that isn'tResult<(), TimeoutError>
. - Despite all these changes,
Awaitable
remains 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
TimeoutError
has been introduced as the defaultAwaitableError
forManualResetEvent
,AutoResetEvent
, and any otherAwaitable
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 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
Awaitable
trait 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.