summaryrefslogtreecommitdiffhomepage
path: root/talpid-windows/src/sync.rs
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2023-10-17 11:24:08 +0200
committerDavid Lönnhager <david.l@mullvad.net>2023-10-20 18:17:06 +0200
commitb3cc38c2bea1869e495206ec1febc6a92bb300bc (patch)
tree6c9663ef925b5699db8c2befcb5fa910b0e28deb /talpid-windows/src/sync.rs
parent5f5e7b3c0e4b14cd8cbd4e53919e3555e24319ed (diff)
downloadmullvadvpn-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.rs75
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,
+ }
+}