wavecraft_dev_server/reload/
guard.rs1use std::sync::atomic::{AtomicBool, Ordering};
7
8pub struct BuildGuard {
13 building: AtomicBool,
14 pending: AtomicBool,
15}
16
17impl BuildGuard {
18 pub fn new() -> Self {
19 Self {
20 building: AtomicBool::new(false),
21 pending: AtomicBool::new(false),
22 }
23 }
24
25 pub fn try_start(&self) -> bool {
27 self.building
28 .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
29 .is_ok()
30 }
31
32 pub fn mark_pending(&self) {
34 self.pending.store(true, Ordering::SeqCst);
35 }
36
37 pub fn complete(&self) -> bool {
39 self.building.store(false, Ordering::SeqCst);
40 self.pending.swap(false, Ordering::SeqCst)
41 }
42}
43
44impl Default for BuildGuard {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn test_build_guard_single_build() {
56 let guard = BuildGuard::new();
57
58 assert!(guard.try_start());
60
61 assert!(!guard.try_start());
63
64 assert!(!guard.complete());
66
67 assert!(guard.try_start());
69 guard.complete();
70 }
71
72 #[test]
73 fn test_build_guard_pending() {
74 let guard = BuildGuard::new();
75
76 assert!(guard.try_start());
78
79 assert!(!guard.try_start());
81
82 guard.mark_pending();
84
85 assert!(guard.complete());
87
88 assert!(guard.try_start());
90 assert!(!guard.complete());
91 }
92
93 #[test]
94 fn test_build_guard_multiple_pending() {
95 let guard = BuildGuard::new();
96
97 assert!(guard.try_start());
99
100 guard.mark_pending();
102 guard.mark_pending();
103 guard.mark_pending();
104
105 assert!(guard.complete());
107
108 assert!(!guard.complete());
110 }
111}