1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use core::fmt;
use std::io;
use std::ptr;
use windows_sys::Win32::Foundation::{GetLastError, ERROR_ALREADY_EXISTS, TRUE};
use windows_sys::Win32::System::Threading::CreateMutexW;
use crate::convert::ToWide;
use crate::error::ErrorKind::*;
use crate::windows::{FromRawHandle, OwnedHandle};
use crate::Result;
/// A named exclusive mutex that can be used to ensure that only one instance of
/// an application is running.
///
/// # Examples
///
/// ```no_run
/// use winctx::NamedMutex;
///
/// if let Some(_m) = NamedMutex::create_acquired("se.tedro.Example")? {
/// // The only one holding the mutex.
/// }
/// # Ok::<_, winctx::Error>(())
/// ```
pub struct NamedMutex {
_handle: OwnedHandle,
}
impl NamedMutex {
/// Create a named mutex with the given name that is already acquired.
///
/// Returns `None` if the mutex could not be acquired.
///
/// # Errors
///
/// Errors in case the named mutex could not be created.
///
/// # Examples
///
/// ```no_run
/// use winctx::NamedMutex;
///
/// if let Some(_m) = NamedMutex::create_acquired("se.tedro.Example")? {
/// // The only one holding the mutex.
/// }
/// # Ok::<_, winctx::Error>(())
/// ```
pub fn create_acquired<N>(name: N) -> Result<Option<Self>>
where
N: fmt::Display,
{
let name = name.to_string();
let name = name.to_wide_null();
unsafe {
let handle = CreateMutexW(ptr::null(), TRUE, name.as_ptr());
if handle.is_null() {
return Err(CreateMutex(io::Error::last_os_error()).into());
}
let handle = OwnedHandle::from_raw_handle(handle as *mut _);
if GetLastError() == ERROR_ALREADY_EXISTS {
return Ok(None);
}
Ok(Some(NamedMutex { _handle: handle }))
}
}
}