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
73
74
75
76
77
78
79
80
use std::io;
use std::ptr;
use winapi::ctypes::c_long;
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
use winapi::shared::ntdef::HANDLE;
use winapi::um::consoleapi::SetConsoleCtrlHandler;
use winapi::um::handleapi::CloseHandle;
use winapi::um::synchapi::{ReleaseSemaphore, WaitForSingleObject};
use winapi::um::winbase::{CreateSemaphoreA, INFINITE, WAIT_FAILED, WAIT_OBJECT_0};
pub type Error = io::Error;
pub type Signal = DWORD;
const MAX_SEM_COUNT: c_long = 255;
static mut SEMAPHORE: HANDLE = 0 as HANDLE;
unsafe extern "system" fn os_handler(_: DWORD) -> BOOL {
ReleaseSemaphore(SEMAPHORE, 1, ptr::null_mut());
TRUE
}
#[inline]
pub unsafe fn init_os_handler() -> Result<(), Error> {
SEMAPHORE = CreateSemaphoreA(ptr::null_mut(), 0, MAX_SEM_COUNT, ptr::null());
if SEMAPHORE.is_null() {
return Err(io::Error::last_os_error());
}
if SetConsoleCtrlHandler(Some(os_handler), TRUE) == FALSE {
let e = io::Error::last_os_error();
CloseHandle(SEMAPHORE);
SEMAPHORE = 0 as HANDLE;
return Err(e);
}
Ok(())
}
#[inline]
pub unsafe fn block_ctrl_c() -> Result<(), Error> {
match WaitForSingleObject(SEMAPHORE, INFINITE) {
WAIT_OBJECT_0 => Ok(()),
WAIT_FAILED => Err(io::Error::last_os_error()),
ret => Err(io::Error::new(
io::ErrorKind::Other,
format!(
"WaitForSingleObject(), unexpected return value \"{:x}\"",
ret
),
)),
}
}