fennec_common/
sync_state.rs1use parking_lot::{Condvar, Mutex};
8use std::{
9 path::PathBuf,
10 sync::atomic::{AtomicBool, Ordering},
11 time::Duration,
12};
13
14use crate::workspace;
15
16#[derive(Default)]
17pub struct VfsChangeBuffer {
18 pub exit: bool,
19 pub scan_roots: Vec<PathBuf>,
21 pub force_scan: bool,
22}
23
24#[derive(Default)]
25pub struct CoreChangeBuffer {
26 pub exit: bool,
27 pub module_updates: Vec<workspace::ModuleUpdate>,
28}
29
30pub struct SyncState {
31 vfs_changes: Mutex<VfsChangeBuffer>,
32 vfs_condvar: Condvar,
33 core_changes: Mutex<CoreChangeBuffer>,
34 core_changed: AtomicBool,
35 core_condvar: Condvar,
36}
37
38impl SyncState {
39 #[must_use]
40 pub fn new() -> SyncState {
41 SyncState {
42 vfs_changes: Mutex::new(VfsChangeBuffer::default()),
43 vfs_condvar: Condvar::new(),
44 core_changes: Mutex::new(CoreChangeBuffer::default()),
45 core_changed: AtomicBool::new(false),
46 core_condvar: Condvar::new(),
47 }
48 }
49
50 fn notify_vfs(&self) {
51 self.vfs_condvar.notify_one();
52 }
53
54 fn notify_core(&self) {
55 self.core_changed.store(true, Ordering::Release);
56 self.core_condvar.notify_one();
57 }
58
59 pub fn is_core_changed(&self) -> bool {
60 self.core_changed.load(Ordering::Acquire)
61 }
62
63 pub fn signal_exit(&self) {
64 {
65 let mut vfs = self.vfs_changes.lock();
66 vfs.exit = true;
67 self.notify_vfs();
68 }
69 {
70 let mut core = self.core_changes.lock();
71 core.exit = true;
72 self.notify_core();
73 }
74 }
75
76 pub fn signal_vfs_new_roots(&self, roots: Vec<PathBuf>) {
77 let mut vfs = self.vfs_changes.lock();
78 vfs.scan_roots.extend(roots);
79 self.notify_vfs();
80 }
81
82 pub fn signal_vfs_force_scan(&self) {
83 let mut vfs = self.vfs_changes.lock();
84 vfs.force_scan = true;
85 self.notify_vfs();
86 }
87
88 pub fn signal_core_module_updates(&self, updates: Vec<workspace::ModuleUpdate>) {
89 let mut core = self.core_changes.lock();
90 core.module_updates.extend(updates);
91 self.notify_core();
92 }
93
94 pub fn wait_vfs(&self, timeout: Duration) -> (VfsChangeBuffer, bool) {
95 let mut vfs = self.vfs_changes.lock();
96 let res = self.vfs_condvar.wait_for(&mut vfs, timeout);
97 (std::mem::take(&mut vfs), res.timed_out())
98 }
99
100 pub fn wait_core(&self) -> CoreChangeBuffer {
101 let mut core = self.core_changes.lock();
102 self.core_condvar.wait(&mut core);
103 std::mem::take(&mut core)
104 }
105}
106
107impl Default for SyncState {
108 fn default() -> Self {
109 Self::new()
110 }
111}