win-events 0.0.2

A poor attempt to implement WaitForMultipleObjects and the ManualReset, AutoReset and Pulse types
Documentation
use std::collections::LinkedList;
use std::error::Error;
use std::sync::{Arc, Condvar, Mutex, MutexGuard};

/// Wait info that gets registered with an EventState, with the position of the Event in a given
/// Vec<dyn Event> used in one of the wait functions
#[derive(Clone)]
pub(crate) struct WaitInfo {
    pub(crate) pos: usize,
    pub(crate) signaler: Arc<dyn Signaler>,
}

/// Trait for abstracting a signaler for a constructed wait object
pub(crate) trait Signaler: Send + Sync {
    fn fire(&self, pos: usize) -> Result<(), Box<dyn Error>>;
    fn clear(&self, pos: usize) -> Result<(), Box<dyn Error>>;
}

pub(crate) struct Waiter<Data> {
    d: Mutex<Data>,
    pub(crate) condvar: Condvar,
}

impl<Data> Waiter<Data> {
    pub(crate) fn new(d: Data) -> Waiter<Data> {
        Waiter {
            d: Mutex::new(d),
            condvar: Condvar::new(),
        }
    }

    pub(crate) fn lock(&self) -> Result<MutexGuard<Data>, Box<dyn Error>> {
        let lock = self.d.lock();
        match lock {
            Ok(data) => Ok(data),
            Err(error) => {
                return Err(format!("Failed to grab wait mutex: {}", error).into());
            }
        }
    }
}

pub(crate) struct WaitList {
    waiters: Mutex<LinkedList<WaitInfo>>,
}

impl WaitList {
    pub(crate) fn new() -> WaitList {
        WaitList {
            waiters: Mutex::new(LinkedList::new()),
        }
    }

    pub(crate) fn fire(&self) {
        let result = self.waiters.lock();
        let waiters = match result {
            Ok(waiters) => waiters,
            Err(_) => return,
        };

        for waiter in waiters.iter() {
            let result = waiter.signaler.fire(waiter.pos);
            match result {
                Ok(_) => {}
                Err(_) => {}
            }
        }
    }

    pub(crate) fn clear(&self) {
        let result = self.waiters.lock();
        let waiters = match result {
            Ok(waiters) => waiters,
            Err(_) => return,
        };

        for waiter in waiters.iter() {
            let result = waiter.signaler.clear(waiter.pos);
            match result {
                Ok(_) => {}
                Err(_) => {}
            }
        }
    }

    pub(crate) fn register_signaler(
        &self,
        pos: usize,
        signaler: Arc<dyn Signaler>,
    ) -> Result<(), Box<dyn Error>> {
        let result = self.waiters.lock();

        match result {
            Ok(mut waiters) => {
                waiters.push_back(WaitInfo { pos, signaler });
                Ok(())
            }
            Err(error) => Err(format!("Could not grab registered waiters lock {}", error).into()),
        }
    }

    pub(crate) fn remove_signaler(
        &self,
        signaler: &Arc<dyn Signaler>,
    ) -> Result<(), Box<dyn Error>> {
        let result = self.waiters.lock();

        match result {
            Ok(mut waiters) => {
                *waiters = {
                    let list = waiters.clone();
                    let iter = list.into_iter();
                    let filtered = iter.filter(|info| Arc::ptr_eq(&info.signaler, signaler));
                    filtered.collect()
                };
                Ok(())
            }
            Err(error) => Err(format!("Could not grab registered waiters lock {}", error).into()),
        }
    }
}