use std::collections::LinkedList;
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, WaitInfo};
use crate::{wait_one, Event};
struct WaitPair {
set: LinkedList<WaitInfo>,
not: LinkedList<WaitInfo>,
}
struct Waiters {
pair: Mutex<WaitPair>,
}
impl Waiters {
fn new() -> Waiters {
let pair = WaitPair {
set: LinkedList::new(),
not: LinkedList::new(),
};
Waiters {
pair: Mutex::new(pair),
}
}
fn fire(&self) {
let pair = match self.pair.lock() {
Ok(pair) => pair,
Err(_) => return,
};
for info in &pair.set {
match info.signaler.fire(info.pos) {
_ => {}
}
}
for info in &pair.not {
match info.signaler.clear(info.pos) {
_ => {}
}
}
}
fn clear(&self) {
let pair = match self.pair.lock() {
Ok(pair) => pair,
Err(_) => return,
};
for info in &pair.not {
match info.signaler.fire(info.pos) {
_ => {}
}
}
for info in &pair.set {
match info.signaler.clear(info.pos) {
_ => {}
}
}
}
fn fire_not(&self) {
self.clear()
}
fn clear_not(&self) {
self.fire()
}
fn register_signaler_is_set(
&self,
pos: usize,
signaler: Arc<dyn Signaler>,
) -> Result<(), Box<dyn Error>> {
let mut pair = match self.pair.lock() {
Ok(pair) => pair,
Err(error) => {
return Err(format!("Could not lock wait list: {}", error).into());
}
};
let info = WaitInfo { pos, signaler };
pair.set.push_back(info);
Ok(())
}
fn remove_signaler_is_set(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
let mut pair = match self.pair.lock() {
Ok(pair) => pair,
Err(error) => {
return Err(format!("Could not lock wait list: {}", error).into());
}
};
pair.set = {
let list = pair.set.clone();
let iter = list.into_iter();
let filtered = iter.filter(|info| Arc::ptr_eq(&info.signaler, signaler));
filtered.collect()
};
Ok(())
}
fn register_signaler_not_set(
&self,
pos: usize,
signaler: Arc<dyn Signaler>,
) -> Result<(), Box<dyn Error>> {
let mut pair = match self.pair.lock() {
Ok(pair) => pair,
Err(error) => {
return Err(format!("Could not lock wait list: {}", error).into());
}
};
let info = WaitInfo { pos, signaler };
pair.not.push_back(info);
Ok(())
}
fn remove_signaler_not_set(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
let mut pair = match self.pair.lock() {
Ok(pair) => pair,
Err(error) => {
return Err(format!("Could not lock wait list: {}", error).into());
}
};
pair.not = {
let list = pair.set.clone();
let iter = list.into_iter();
let filtered = iter.filter(|info| Arc::ptr_eq(&info.signaler, signaler));
filtered.collect()
};
Ok(())
}
}
struct ManualResetEventPairInfo {
fired: AtomicBool,
waiters: Waiters,
}
impl ManualResetEventPairInfo {
fn new(init: bool) -> ManualResetEventPairInfo {
ManualResetEventPairInfo {
fired: AtomicBool::new(init),
waiters: Waiters::new(),
}
}
}
struct ManualResetEventSetInfo {
info: Arc<ManualResetEventPairInfo>,
}
impl EventState for ManualResetEventSetInfo {
fn is_set(&self) -> bool {
self.info.fired.load(Ordering::Relaxed)
}
fn set(&self) {
self.info.fired.store(true, Ordering::Relaxed);
self.info.waiters.fire();
}
fn clear(&self) {
self.info.fired.store(false, Ordering::Relaxed);
self.info.waiters.clear();
}
fn register_signaler(
&self,
pos: usize,
signaler: Arc<dyn Signaler>,
) -> Result<(), Box<dyn Error>> {
if self.is_set() {
signaler.fire(pos)?
}
self.info.waiters.register_signaler_is_set(pos, signaler)
}
fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
self.info.waiters.remove_signaler_is_set(signaler)
}
fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
Ok(None)
}
fn can_consume(&self) -> bool {
self.is_set()
}
fn consume(&self) {}
}
struct ManualResetEventNotSetInfo {
info: Arc<ManualResetEventPairInfo>,
}
impl EventState for ManualResetEventNotSetInfo {
fn is_set(&self) -> bool {
!self.info.fired.load(Ordering::Relaxed)
}
fn set(&self) {
self.info.fired.store(false, Ordering::Relaxed);
self.info.waiters.fire_not()
}
fn clear(&self) {
self.info.fired.store(true, Ordering::Relaxed);
self.info.waiters.clear_not();
}
fn register_signaler(
&self,
pos: usize,
signaler: Arc<dyn Signaler>,
) -> Result<(), Box<dyn Error>> {
if self.is_set() {
signaler.fire(pos)?
}
self.info.waiters.register_signaler_not_set(pos, signaler)
}
fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
self.info.waiters.remove_signaler_not_set(signaler)
}
fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
Ok(None)
}
fn can_consume(&self) -> bool {
self.is_set()
}
fn consume(&self) {}
}
#[derive(Clone)]
pub struct ManualResetEventPair {
pair: Arc<ManualResetEventPairInfo>,
info: Arc<EventHandle>,
}
impl ManualResetEventPair {
pub fn new(init: bool) -> ManualResetEventPair {
let pair = Arc::new(ManualResetEventPairInfo::new(init));
let state: Box<dyn EventState> = Box::new(ManualResetEventSetInfo {
info: Arc::clone(&pair),
});
let info = Arc::new(EventHandle::new(state));
ManualResetEventPair { pair, info }
}
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)
}
pub fn event_set(&self) -> ManualResetEventPair {
let pair = Arc::clone(&self.pair);
let state: Box<dyn EventState> = Box::new(ManualResetEventSetInfo {
info: Arc::clone(&pair),
});
let info = Arc::new(EventHandle::new(state));
ManualResetEventPair { pair, info }
}
pub fn event_not_set(&self) -> ManualResetEventPair {
let pair = Arc::clone(&self.pair);
let state: Box<dyn EventState> = Box::new(ManualResetEventNotSetInfo {
info: Arc::clone(&pair),
});
let info = Arc::new(EventHandle::new(state));
ManualResetEventPair { pair, info }
}
}
impl Event for ManualResetEventPair {
fn handle(&self) -> &Arc<EventHandle> {
&self.info
}
}