Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/cli/src/util/app_lock.rs
3314 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
#[cfg(windows)]
7
use std::{io, ptr};
8
9
#[cfg(windows)]
10
use winapi::{
11
shared::winerror::ERROR_ALREADY_EXISTS,
12
um::{handleapi::CloseHandle, synchapi::CreateMutexA, winnt::HANDLE},
13
};
14
15
use super::errors::CodeError;
16
17
pub struct AppMutex {
18
#[cfg(windows)]
19
handle: HANDLE,
20
}
21
22
#[cfg(windows)] // handle is thread-safe, mark it so with this
23
unsafe impl Send for AppMutex {}
24
25
impl AppMutex {
26
#[cfg(unix)]
27
pub fn new(_name: &str) -> Result<Self, CodeError> {
28
Ok(Self {})
29
}
30
31
#[cfg(windows)]
32
pub fn new(name: &str) -> Result<Self, CodeError> {
33
use std::ffi::CString;
34
35
let cname = CString::new(name).unwrap();
36
let handle = unsafe { CreateMutexA(ptr::null_mut(), 0, cname.as_ptr() as _) };
37
38
if !handle.is_null() {
39
return Ok(Self { handle });
40
}
41
42
let err = io::Error::last_os_error();
43
let raw = err.raw_os_error();
44
// docs report it should return ERROR_IO_PENDING, but in my testing it actually
45
// returns ERROR_LOCK_VIOLATION. Or maybe winapi is wrong?
46
if raw == Some(ERROR_ALREADY_EXISTS as i32) {
47
return Err(CodeError::AppAlreadyLocked(name.to_string()));
48
}
49
50
Err(CodeError::AppLockFailed(err))
51
}
52
}
53
54
impl Drop for AppMutex {
55
fn drop(&mut self) {
56
#[cfg(windows)]
57
unsafe {
58
CloseHandle(self.handle)
59
};
60
}
61
}
62
63