use parking_lot::{Condvar, Mutex};
use std::num::Wrapping;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, Instant};
pub trait ResetEvent {
fn reset(&self);
fn set(&self);
fn wait(&self);
fn wait_until(&self, instant: Instant) -> bool;
fn wait_duration(&self, duration: Duration) -> bool {
self.wait_until(Instant::now() + duration)
}
fn wait_ms(&self, milliseconds: u64) -> bool {
self.wait_duration(Duration::from_millis(milliseconds))
}
}
pub struct AutoResetEvent {
value: Mutex<bool>,
condition: Condvar,
}
impl AutoResetEvent {
pub fn new(signalled: bool) -> AutoResetEvent {
AutoResetEvent {
value: Mutex::new(signalled),
condition: Condvar::new(),
}
}
}
impl ResetEvent for AutoResetEvent {
fn reset(&self) {
*self.value.lock() = false;
}
fn set(&self) {
*self.value.lock() = true;
self.condition.notify_one();
}
fn wait(&self) {
let mut value = self.value.lock();
while !*value {
self.condition.wait(&mut value);
}
*value = false;
}
fn wait_until(&self, instant: Instant) -> bool {
let mut value = self.value.lock();
while !*value {
if self.condition.wait_until(&mut value, instant).timed_out() {
return false;
}
}
*value = false;
true
}
}
pub struct ManualResetEvent {
value: Mutex<ManualResetEventData>,
condition: Condvar,
}
impl ManualResetEvent {
pub fn new(signalled: bool) -> ManualResetEvent {
let id = Wrapping(0);
ManualResetEvent {
value: Mutex::new(ManualResetEventData { signalled, id }),
condition: Condvar::new(),
}
}
}
struct ManualResetEventData {
id: Wrapping<usize>,
signalled: bool,
}
impl ResetEvent for ManualResetEvent {
fn reset(&self) {
self.value.lock().signalled = false;
}
fn set(&self) {
let mut value = self.value.lock();
value.id += Wrapping(1);
value.signalled = true;
self.condition.notify_all();
}
fn wait(&self) {
let mut value = self.value.lock();
let id = value.id;
while !value.signalled && value.id == id {
self.condition.wait(&mut value);
}
}
fn wait_until(&self, instant: Instant) -> bool {
let mut value = self.value.lock();
let id = value.id;
while !value.signalled && value.id == id {
if self.condition.wait_until(&mut value, instant).timed_out() {
return false;
}
}
true
}
}
#[derive(Debug)]
pub struct AtomicArBool {
value: AtomicBool,
}
impl AtomicArBool {
pub const fn new(value: bool) -> AtomicArBool {
AtomicArBool {
value: AtomicBool::new(value),
}
}
pub fn get(&self) -> bool {
self.value.load(Ordering::Acquire)
}
pub fn set(&self, value: bool) {
self.value.store(value, Ordering::Release)
}
}
impl Default for AtomicArBool {
fn default() -> AtomicArBool {
AtomicArBool {
value: AtomicBool::default(),
}
}
}
#[derive(Debug)]
pub struct AtomicRelaxedBool {
value: AtomicBool,
}
impl AtomicRelaxedBool {
pub const fn new(value: bool) -> AtomicRelaxedBool {
AtomicRelaxedBool {
value: AtomicBool::new(value),
}
}
pub fn get(&self) -> bool {
self.value.load(Ordering::Relaxed)
}
pub fn set(&self, value: bool) {
self.value.store(value, Ordering::Relaxed)
}
}
impl Default for AtomicRelaxedBool {
fn default() -> AtomicRelaxedBool {
AtomicRelaxedBool {
value: AtomicBool::default(),
}
}
}