diff options
| author | David Lönnhager <david.l@mullvad.net> | 2023-10-17 11:24:08 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2023-10-20 18:17:06 +0200 |
| commit | b3cc38c2bea1869e495206ec1febc6a92bb300bc (patch) | |
| tree | 6c9663ef925b5699db8c2befcb5fa910b0e28deb /talpid-windows/src/sync.rs | |
| parent | 5f5e7b3c0e4b14cd8cbd4e53919e3555e24319ed (diff) | |
| download | mullvadvpn-b3cc38c2bea1869e495206ec1febc6a92bb300bc.tar.xz mullvadvpn-b3cc38c2bea1869e495206ec1febc6a92bb300bc.zip | |
Move Event and Overlapped to talpid-windows crate
Diffstat (limited to 'talpid-windows/src/sync.rs')
| -rw-r--r-- | talpid-windows/src/sync.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/talpid-windows/src/sync.rs b/talpid-windows/src/sync.rs new file mode 100644 index 0000000000..7b4ed59be3 --- /dev/null +++ b/talpid-windows/src/sync.rs @@ -0,0 +1,75 @@ +use std::{io, ptr}; +use windows_sys::Win32::{ + Foundation::{CloseHandle, DuplicateHandle, BOOL, DUPLICATE_SAME_ACCESS, HANDLE}, + System::Threading::{CreateEventW, GetCurrentProcess, SetEvent}, +}; + +/// Windows event object +pub struct Event(HANDLE); + +unsafe impl Send for Event {} +unsafe impl Sync for Event {} + +impl Event { + /// Create a new event object using `CreateEventW` + pub fn new(manual_reset: bool, initial_state: bool) -> io::Result<Self> { + let event = unsafe { + CreateEventW( + ptr::null_mut(), + bool_to_winbool(manual_reset), + bool_to_winbool(initial_state), + ptr::null(), + ) + }; + if event == 0 { + return Err(io::Error::last_os_error()); + } + Ok(Self(event)) + } + + /// Signal the event object + pub fn set(&self) -> io::Result<()> { + if unsafe { SetEvent(self.0) } == 0 { + return Err(io::Error::last_os_error()); + } + Ok(()) + } + + /// Return raw event object + pub fn as_raw(&self) -> HANDLE { + self.0 + } + + /// Duplicate the event object with `DuplicateHandle()` + pub fn duplicate(&self) -> io::Result<Event> { + let mut new_event = 0; + let status = unsafe { + DuplicateHandle( + GetCurrentProcess(), + self.0, + GetCurrentProcess(), + &mut new_event, + 0, + 0, + DUPLICATE_SAME_ACCESS, + ) + }; + if status == 0 { + return Err(io::Error::last_os_error()); + } + Ok(Event(new_event)) + } +} + +impl Drop for Event { + fn drop(&mut self) { + unsafe { CloseHandle(self.0) }; + } +} + +const fn bool_to_winbool(val: bool) -> BOOL { + match val { + true => 1, + false => 0, + } +} |
