1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
use crate::prelude::*; use crate::utils::*; use std::sync::{Arc, Condvar, Mutex}; pub struct SpinLoopWaitStrategy; pub struct BlockingWaitStrategy { guard: Mutex<()>, cvar: Condvar, } impl WaitStrategy for SpinLoopWaitStrategy { fn new() -> Self { SpinLoopWaitStrategy {} } fn wait_for<F: Fn() -> bool>( &self, sequence: Sequence, dependencies: &[Arc<AtomicSequence>], check_alert: F, ) -> Option<Sequence> { loop { let available = min_cursor_sequence(dependencies); if available >= sequence { return Some(available); } if check_alert() { return None; } } } fn signal(&self) {} } impl WaitStrategy for BlockingWaitStrategy { fn new() -> Self { BlockingWaitStrategy { cvar: Condvar::new(), guard: Mutex::new(()), } } fn wait_for<F: Fn() -> bool>( &self, sequence: Sequence, dependencies: &[Arc<AtomicSequence>], check_alert: F, ) -> Option<Sequence> { loop { let blocked = self.guard.lock().unwrap(); if check_alert() { return None; } let available = min_cursor_sequence(dependencies); if available >= sequence { return Some(available); } else { let _ = self.cvar.wait(blocked).unwrap(); } } } fn signal(&self) { let _ = self.guard.lock().unwrap(); self.cvar.notify_all(); } }