use std::error::Error;
use std::sync::{Arc, MutexGuard};
use crate::waiters::waiter::Signaler;
pub(crate) trait EventState: Send + Sync {
fn is_set(&self) -> bool;
fn set(&self);
fn clear(&self);
fn register_signaler(
&self,
pos: usize,
signaler: Arc<dyn Signaler>,
) -> Result<(), Box<dyn Error>>;
fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>>;
fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>>;
fn can_consume(&self) -> bool;
fn consume(&self);
}
pub struct EventHandle {
state: Box<dyn EventState>,
}
impl EventHandle {
pub(crate) fn new(state: Box<dyn EventState>) -> EventHandle {
EventHandle { state }
}
pub(crate) fn is_set(&self) -> bool {
self.state.is_set()
}
pub(crate) fn set(&self) {
self.state.set()
}
pub(crate) fn clear(&self) {
self.state.clear()
}
pub(crate) fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
self.state.wake_lock()
}
pub(crate) fn can_consume(&self) -> bool {
self.state.can_consume()
}
pub(crate) fn consume(&self) {
self.state.consume()
}
}
pub trait Event: Sync {
fn handle(&self) -> &Arc<EventHandle>;
}
pub(crate) fn try_consume_one(event: &dyn Event) -> Result<bool, Box<dyn Error>> {
let _ = event.handle().wake_lock()?;
if event.handle().can_consume() {
event.handle().consume();
Ok(true)
} else {
Ok(false)
}
}
pub(crate) fn try_consume_all(events: &Vec<&dyn Event>) -> Result<bool, Box<dyn Error>> {
let mut locks = Vec::with_capacity(events.len());
for event in events {
let wake_lock = event.handle().wake_lock()?;
if !event.handle().can_consume() {
return Ok(false);
}
locks.push(wake_lock)
}
for event in events {
event.handle().consume()
}
Ok(true)
}
pub(crate) struct AutoUnregister {
signaler: Arc<dyn Signaler>,
handle: Arc<EventHandle>,
}
impl AutoUnregister {
pub(crate) fn new(signaler: Arc<dyn Signaler>, handle: Arc<EventHandle>) -> AutoUnregister {
AutoUnregister { signaler, handle }
}
pub(crate) fn register_signaler(
signaler: Arc<dyn Signaler>,
pos: usize,
event: &dyn Event,
) -> Result<AutoUnregister, Box<dyn Error>> {
let auto_unregister =
AutoUnregister::new(Arc::clone(&signaler), Arc::clone(event.handle()));
event.handle().state.register_signaler(pos, signaler)?;
Ok(auto_unregister)
}
}
impl Drop for AutoUnregister {
fn drop(&mut self) {
match self.handle.state.remove_signaler(&self.signaler) {
_ => {}
}
}
}
pub struct EventGuard {
handle: Arc<EventHandle>,
}
impl EventGuard {
pub fn new(event: &dyn Event) -> EventGuard {
let handle = Arc::clone(event.handle());
handle.set();
EventGuard { handle }
}
}
impl Drop for EventGuard {
fn drop(&mut self) {
self.handle.clear()
}
}