synchronoise::event

Struct CountdownEvent

Source
pub struct CountdownEvent { /* private fields */ }
Expand description

A synchronization primitive that signals when its count reaches zero.

With a CountdownEvent, it’s possible to cause one thread to wait on a set of computations occurring in other threads by making the other threads interact with the counter as they perform their work.

The main limitation of a CountdownEvent is that once its counter reaches zero (even by starting there), any attempts to update the counter will return CountdownError::AlreadySet until the counter is reset by calling reset or reset_to_count.

CountdownEvent is a port of System.Threading.CountdownEvent from .NET (also called CountDownLatch in Java).

§Example

This example uses a CountdownEvent to make the “coordinator” thread sleep until all of its “worker” threads have finished. Each thread calls signal.decrement() to signal to the Event that its work has completed. When the last thread does this (and brings the counter to zero), the “coordinator” thread wakes up and prints all done!.

use synchronoise::CountdownEvent;
use std::sync::Arc;
use std::thread;
use std::time::Duration;

let thread_count = 5;
let counter = Arc::new(CountdownEvent::new(thread_count));

for i in 0..thread_count {
    let signal = counter.clone();
    thread::spawn(move || {
        thread::sleep(Duration::from_secs(i as u64));
        println!("thread {} activated!", i);
        signal.decrement().unwrap();
    });
}

counter.wait();

println!("all done!");

Implementations§

Source§

impl CountdownEvent

Source

pub fn new(count: usize) -> CountdownEvent

Creates a new CountdownEvent, initialized to the given count.

Remember that once the counter reaches zero, calls to add or signal will fail, so passing zero to this function will create a CountdownEvent that is permanently signaled.

Source

pub fn reset(&mut self)

Resets the counter to the count given to new.

This function is safe because the &mut self enforces that no other references or locks exist.

Source

pub fn reset_to_count(&mut self, count: usize)

Resets the counter to the given count.

This function is safe because the &mut self enforces that no other references or locks exist.

Source

pub fn count(&self) -> usize

Returns the current counter value.

Source

pub fn add(&self, count: usize) -> Result<(), CountdownError>

Adds the given count to the counter.

§Errors

If the counter is already at zero, this function will return CountdownError::AlreadySet.

If the given count would cause the counter to overflow usize, this function will return CountdownError::SaturatedCounter.

Source

pub fn signal(&self, count: usize) -> Result<bool, CountdownError>

Subtracts the given count to the counter, and returns whether this caused any waiting threads to wake up.

§Errors

If the counter is already at zero, this function will return CountdownError::AlreadySet.

If the given count would cause the counter to go below zero (instead of reaching zero), this function will return CountdownError::TooManySignals.

Source

pub fn increment(&self) -> Result<(), CountdownError>

Adds one to the count.

§Errors

See add for the situations where this function will return an error.

Source

pub fn decrement(&self) -> Result<bool, CountdownError>

Subtracts one from the counter, and returns whether this caused any waiting threads to wake up.

§Errors

See signal for the situations where this function will return an error.

Source

pub fn guard(&self) -> Result<CountdownGuard<'_>, CountdownError>

Increments the counter, then returns a guard object that will decrement the counter upon drop.

§Errors

This function will return the same errors as add. If the event has already signaled by the time the guard is dropped (and would cause its decrement call to return an error), then the error will be silently ignored.

§Example

Here’s the sample from the main docs, using CountdownGuards instead of manually decrementing:

use synchronoise::CountdownEvent;
use std::sync::Arc;
use std::thread;
use std::time::Duration;

let thread_count = 5;
// counter can't start from zero, but the guard increments on its own, so start at one and
// just decrement once when we're ready to wait
let counter = Arc::new(CountdownEvent::new(1));

for i in 0..thread_count {
    let signal = counter.clone();
    thread::spawn(move || {
        let _guard = signal.guard().unwrap();
        thread::sleep(Duration::from_secs(i));
        println!("thread {} activated!", i);
    });
}

// give all the threads time to increment the counter before continuing
thread::sleep(Duration::from_millis(100));
counter.decrement().unwrap();
counter.wait();

println!("all done!");
Source

pub fn wait(&self)

Blocks the current thread until the counter reaches zero.

This function will block indefinitely until the counter reaches zero. It will return immediately if it is already at zero.

Source

pub fn wait_timeout(&self, timeout: Duration) -> usize

Blocks the current thread until the timer reaches zero, or until the given timeout elapses, returning the count at the time of wakeup.

This function will return immediately if the counter was already at zero. Otherwise, it will block for roughly no longer than timeout, or when the counter reaches zero, whichever comes first.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 384 bytes