use std::error::Error;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, MutexGuard};
use std::time::Duration;
use crate::events::event::{EventHandle, EventState};
use crate::waiters::waiter::{Signaler, WaitList};
use crate::{wait_one, Event};
struct ManualResetEventInfo {
fired: AtomicBool,
waiters: WaitList,
}
impl ManualResetEventInfo {
fn new(init: bool) -> ManualResetEventInfo {
ManualResetEventInfo {
fired: AtomicBool::new(init),
waiters: WaitList::new(),
}
}
}
impl EventState for ManualResetEventInfo {
fn is_set(&self) -> bool {
self.fired.load(Ordering::Relaxed)
}
fn set(&self) {
self.fired.store(true, Ordering::Relaxed);
self.waiters.fire()
}
fn clear(&self) {
self.fired.store(false, Ordering::Relaxed);
self.waiters.clear();
}
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>> {
Ok(None)
}
fn can_consume(&self) -> bool {
self.fired.load(Ordering::Relaxed)
}
fn consume(&self) {}
}
#[derive(Clone)]
pub struct ManualResetEvent {
info: Arc<EventHandle>,
}
impl ManualResetEvent {
pub fn new(init: bool) -> ManualResetEvent {
let state: Box<dyn EventState> = Box::new(ManualResetEventInfo::new(init));
ManualResetEvent {
info: Arc::new(EventHandle::new(state)),
}
}
pub fn is_set(&self) -> bool {
self.info.is_set()
}
pub fn set(&self) {
self.info.set()
}
pub fn clear(&self) {
self.info.clear()
}
pub fn wait(&self, dur: Duration) -> Result<bool, Box<dyn Error>> {
wait_one(self, dur)
}
}
impl Event for ManualResetEvent {
fn handle(&self) -> &Arc<EventHandle> {
&self.info
}
}