cyfs_util/process/
process_mutex.rs1use named_lock::{NamedLock, NamedLockGuard};
2
3extern crate lazy_static;
4use lazy_static::lazy_static;
5use std::sync::Mutex;
6
7pub struct ProcessMutex {
8 prev_lock: NamedLock,
10
11 named_lock: NamedLock,
12}
13
14impl ProcessMutex {
15 pub fn new(service_name: &str) -> ProcessMutex {
16 let name = format!("cyfs_plock_{}", service_name);
17 let named_lock;
18 #[cfg(unix)]
19 {
20 let locks_folder = crate::get_cyfs_root_path().join("run/locks");
21 if !locks_folder.is_dir() {
22 if let Err(e) = std::fs::create_dir_all(&locks_folder) {
23 error!(
24 "create run/locks folder error! folder={}, err={}",
25 locks_folder.display(),
26 e
27 );
28 }
29 }
30
31 let lock_file = locks_folder.join(&format!("{}.lock", name));
32 named_lock = NamedLock::with_path(lock_file).unwrap();
33 }
34 #[cfg(not(unix))]
35 {
36 named_lock = NamedLock::create(&name).unwrap();
37 }
38
39 Self {
40 prev_lock: NamedLock::create(&name).unwrap(),
41 named_lock,
42 }
43 }
44
45 pub fn acquire(&self) -> Option<NamedLockGuard> {
46 match self.prev_lock.try_lock() {
47 Ok(_guard) => {
48 }
50 Err(_) => {
51 return None;
53 }
54 }
55
56 match self.named_lock.try_lock() {
57 Ok(guard) => {
58 Some(guard)
59 }
60
61 Err(_e) => {
62 None
63 }
64 }
65 }
66}
67
68pub(crate) struct ServiceName(String);
69
70impl ServiceName {
71 pub fn new() -> ServiceName {
72 ServiceName("".to_owned())
73 }
74
75 pub fn init(&mut self, service_name: &str) {
76
77 assert!(self.0.is_empty());
79 self.0 = service_name.to_owned();
80 }
81
82 pub fn detach(&mut self) -> String {
83 self.0.split_off(0)
84 }
85}
86
87static mut LOCK_GUARD_HOLDER: Option<NamedLockGuard<'static>> = None;
89
90lazy_static! {
91 pub(crate) static ref SERVICE_NAME: Mutex<ServiceName> = {
92 return Mutex::new(ServiceName::new());
93 };
94
95 pub(crate) static ref CURRENT_PROCESS_MUTEX: ProcessMutex = {
96 let name = SERVICE_NAME.lock().unwrap().detach();
97 assert!(!name.is_empty());
98
99 ProcessMutex::new(&name)
100 };
101
102 pub(crate) static ref CURRENT_PROC_LOCK: bool = {
103 let guard = CURRENT_PROCESS_MUTEX.acquire();
104 if guard.is_none() {
105 false
106 } else {
107 unsafe {
108 LOCK_GUARD_HOLDER = guard;
109 }
110
111 true
112 }
113 };
114}