chat_platform_native/
tab_lock.rs1use std::path::Path;
2
3#[cfg(not(target_arch = "wasm32"))]
9pub struct TabLock {
10 _file: std::fs::File,
11 path: std::path::PathBuf,
12}
13
14#[cfg(target_arch = "wasm32")]
15pub struct TabLock;
16
17impl TabLock {
18 pub fn try_acquire(path: &Path) -> Option<TabLock> {
21 #[cfg(not(target_arch = "wasm32"))]
22 {
23 use fs2::FileExt;
24 let file = std::fs::OpenOptions::new()
25 .write(true)
26 .create(true)
27 .truncate(false)
28 .open(path)
29 .ok()?;
30 file.try_lock_exclusive().ok()?;
31 Some(TabLock {
32 _file: file,
33 path: path.to_path_buf(),
34 })
35 }
36 #[cfg(target_arch = "wasm32")]
37 {
38 let _ = path;
39 Some(TabLock)
40 }
41 }
42}
43
44#[cfg(not(target_arch = "wasm32"))]
45impl Drop for TabLock {
46 fn drop(&mut self) {
47 #[allow(unused_imports)]
48 use fs2::FileExt;
49 let _ = self._file.unlock();
51 let _ = std::fs::remove_file(&self.path);
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn try_acquire_returns_lock_when_file_is_free() {
61 let dir = std::env::temp_dir();
62 let path = dir.join("p2pandemonium-tab-lock-test-1.lock");
63 let _ = std::fs::remove_file(&path);
64 let lock = TabLock::try_acquire(&path);
65 assert!(lock.is_some());
66 drop(lock);
67 let _ = std::fs::remove_file(&path);
68 }
69
70 #[test]
71 fn second_acquire_fails_when_lock_is_held() {
72 let dir = std::env::temp_dir();
73 let path = dir.join("p2pandemonium-tab-lock-test-2.lock");
74 let _ = std::fs::remove_file(&path);
75
76 let lock1 = TabLock::try_acquire(&path);
77 assert!(lock1.is_some());
78
79 let lock2 = TabLock::try_acquire(&path);
80 assert!(lock2.is_none());
81
82 drop(lock1);
83 let _ = std::fs::remove_file(&path);
84 }
85
86 #[test]
87 fn lock_can_be_reacquired_after_release() {
88 let dir = std::env::temp_dir();
89 let path = dir.join("p2pandemonium-tab-lock-test-3.lock");
90 let _ = std::fs::remove_file(&path);
91
92 {
93 let lock = TabLock::try_acquire(&path);
94 assert!(lock.is_some());
95 }
96
97 let lock = TabLock::try_acquire(&path);
98 assert!(lock.is_some());
99 drop(lock);
100 let _ = std::fs::remove_file(&path);
101 }
102}