Expand description
rsignals — a one-shot, multi-signaler / multi-waiter, fail-safe broadcast event.
See plan.md and README.md for the full design. In short, an event has one
shared state with three outcomes:
- Pending — no signal yet, and at least one signaler still exists,
- Fired — some signaler called
signal(); every waiter is released, - Disconnected — every signaler was dropped without firing, so no signal can ever arrive and every waiter is released and told so.
Rules:
- a signal is delivered at most once: the first
signal()wins (Ok(true)), every later attempt reportsOk(false), - if every waiter has been dropped,
signal()reportsNoReceiversand does not fire (there is no one to receive it), - a waiter that arrives after the event is already terminal returns immediately with the same outcome,
- handles are cheap to clone; every clone shares the same underlying state.
§Variants
sync— blockingsync::Waiter::wait, backed by a mutex + condvar.r#async— runtime-agnostic asyncwait(), backed by astd::task::Wakerregistry. (Spelledr#asyncbecauseasyncis a keyword.)
Both share the same error types and the same one-shot
semantics; only the wait side differs (block vs. .await).
§Example (sync)
use std::thread;
let (tx, rx) = rsignals::sync::create();
let rx2 = rx.clone();
let waiter = thread::spawn(move || rx2.wait());
assert_eq!(tx.signal(), Ok(true)); // first signal wins
assert_eq!(waiter.join().unwrap(), Ok(())); // waiter is released
assert_eq!(tx.signal(), Ok(false)); // one-shot: later signals report already-firedRe-exports§
pub use error::Disconnected;pub use error::NoReceivers;pub use error::TryWaitError;pub use error::WaitTimeoutError;