use std::sync::{Condvar, MutexGuard}; use sync42::monitor::{Monitor, MonitorCore}; struct TestState<'a> { cnd: &'a Condvar, } #[derive(Default)] struct TestCoordination { someone_has_it: bool, threads_waiting: usize, } #[derive(Default)] struct TestCriticalSection { count: u64, } #[derive(Default)] struct TestMonitor; impl MonitorCore> for TestMonitor { fn acquire<'a: 'b, 'b>( &self, mut guard: MutexGuard<'a, TestCoordination>, t: &'b mut TestState, ) -> (bool, MutexGuard<'a, TestCoordination>) { while guard.someone_has_it { guard.threads_waiting += 1; guard = t.cnd.wait(guard).unwrap(); guard.threads_waiting -= 1; } guard.someone_has_it = true; (true, guard) } fn release<'a: 'b, 'b>( &self, mut guard: MutexGuard<'a, TestCoordination>, t: &'b mut TestState, ) -> MutexGuard<'a, TestCoordination> { guard.someone_has_it = false; if guard.threads_waiting > 0 { t.cnd.notify_one(); } guard } fn critical_section<'a: 'b, 'b>( &self, crit: &'a mut TestCriticalSection, _t: &'b mut TestState<'_>, ) { crit.count += 1; } } #[test] fn monitor_outside_struct() { let core = TestMonitor; let coordination = TestCoordination::default(); let critical_section = TestCriticalSection::default(); let monitor = Monitor::new(core, coordination, critical_section); let cnd = Condvar::new(); let mut state = TestState { cnd: &cnd }; monitor.do_it(&mut state); } struct TestWithMonitor<'a> { monitor: Monitor, TestMonitor>, } #[test] fn monitor_inside_struct() { let core = TestMonitor; let coordination = TestCoordination::default(); let critical_section = TestCriticalSection::default(); let monitor = Monitor::new(core, coordination, critical_section); let twm = TestWithMonitor { monitor }; let cnd = Condvar::new(); let mut state = TestState { cnd: &cnd }; twm.monitor.do_it(&mut state); }