win-events 0.0.2

A poor attempt to implement WaitForMultipleObjects and the ManualReset, AutoReset and Pulse types
Documentation
use std::error::Error;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, MutexGuard};
use std::time::Duration;

use crate::events::event::{EventHandle, EventState};
use crate::waiters::waiter::{Signaler, WaitList};
use crate::{wait_one, Event};

struct AutoResetEventInfo {
    fired: AtomicBool,
    waiters: WaitList,
    wake_lock: Mutex<()>,
}

impl AutoResetEventInfo {
    fn new(init: bool) -> AutoResetEventInfo {
        AutoResetEventInfo {
            fired: AtomicBool::new(init),
            waiters: WaitList::new(),
            wake_lock: Mutex::new(()),
        }
    }
}

impl AutoResetEventInfo {
    fn set_value(&self, value: bool) {
        self.fired.store(value, Ordering::Relaxed);
        // If there are waiters, fire a signal
        self.waiters.fire()
    }
}

impl EventState for AutoResetEventInfo {
    fn is_set(&self) -> bool {
        self.fired.load(Ordering::Relaxed)
    }

    fn set(&self) {
        self.set_value(true)
    }

    fn clear(&self) {
        self.set_value(false)
    }

    fn register_signaler(
        &self,
        pos: usize,
        signaler: Arc<dyn Signaler>,
    ) -> Result<(), Box<dyn Error>> {
        if self.is_set() {
            signaler.fire(pos)?;
        }
        self.waiters.register_signaler(pos, signaler)
    }

    fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
        self.waiters.remove_signaler(signaler)
    }

    fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
        let result = self.wake_lock.lock();

        match result {
            Ok(guard) => Ok(Some(guard)),
            Err(error) => Err(format!("Could not lock wake mutex: {}", error).into()),
        }
    }

    fn can_consume(&self) -> bool {
        self.fired.load(Ordering::Relaxed)
    }

    fn consume(&self) {
        self.fired.store(false, Ordering::Relaxed)
    }
}

/// A AutoResetEvent
///
/// An event represents a boolean condition that can be waited on until signaled. This allows a
/// thread to block and wait for another thread to set the event. A waiting thread that gets
/// released to continue will consume and automatically reset the event.
///
/// # Examples
///
/// ```
/// use std::thread;
/// use std::time::Duration;
/// use win_events::{Event, AutoResetEvent};
///
/// let evt_started = AutoResetEvent::new(false);
/// let evt_started2 = evt_started.clone();
///
/// // spawn a thread and set the cloned event
/// thread::spawn(move|| {
///     evt_started2.set();
/// });
///
/// // Wait for the started event
/// evt_started.wait(Duration::from_millis(100)).unwrap();
/// assert!(!evt_started.is_set())
/// ```
#[derive(Clone)]
pub struct AutoResetEvent {
    info: Arc<EventHandle>,
}

impl AutoResetEvent {
    /// Creates a new AutoResetEvent and initialized the value.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::AutoResetEvent;
    ///
    /// let evt = AutoResetEvent::new(false);
    /// ```
    pub fn new(init: bool) -> AutoResetEvent {
        let state: Box<dyn EventState> = Box::new(AutoResetEventInfo::new(init));
        AutoResetEvent {
            info: Arc::new(EventHandle::new(state)),
        }
    }

    /// Gets the current state of the event.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::AutoResetEvent;
    ///
    /// let evt = AutoResetEvent::new(true);
    /// assert!(evt.is_set())
    ///  ```
    pub fn is_set(&self) -> bool {
        self.info.is_set()
    }

    /// Sets the event and fires a signal to any threads waiting on the event.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::AutoResetEvent;
    ///
    /// let evt = AutoResetEvent::new(false);
    /// evt.set();
    /// assert!(evt.is_set())
    /// ```
    pub fn set(&self) {
        self.info.set()
    }

    /// Sets the even, causing any waiting threads to receive a signal.
    ///
    /// # Examples
    ///
    /// ```
    /// use win_events::AutoResetEvent;
    ///
    /// let evt = AutoResetEvent::new(false);
    /// evt.clear();
    /// assert!(!evt.is_set())
    /// ```
    pub fn clear(&self) {
        self.info.clear()
    }
    /// Creates a new AutoResetEvent and initialized the value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::thread::{sleep, spawn};
    /// use std::time::Duration;
    /// use win_events::AutoResetEvent;
    ///
    /// let evt = AutoResetEvent::new(false);
    /// let evt_inner = evt.clone();
    ///
    /// let worker = spawn(move || {
    ///    sleep(Duration::from_millis(3));
    ///    evt_inner.set()
    /// });
    ///
    /// let wait_result = evt.wait(Duration::from_millis(100)).unwrap();
    /// assert!(wait_result && !evt.is_set())
    /// ```
    pub fn wait(&self, dur: Duration) -> Result<bool, Box<dyn Error>> {
        wait_one(self, dur)
    }
}

impl Event for AutoResetEvent {
    fn handle(&self) -> &Arc<EventHandle> {
        &self.info
    }
}