6
6
// copied, modified, or distributed except according to those terms.
7
7
8
8
use core:: {
9
+ ffi,
9
10
mem:: { self , MaybeUninit } ,
10
11
ptr,
11
12
} ;
12
13
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
13
14
use std:: time:: Instant ;
14
- use winapi:: {
15
- shared:: {
16
- minwindef:: { TRUE , ULONG } ,
17
- ntdef:: NTSTATUS ,
18
- ntstatus:: { STATUS_SUCCESS , STATUS_TIMEOUT } ,
19
- } ,
20
- um:: {
21
- handleapi:: CloseHandle ,
22
- libloaderapi:: { GetModuleHandleA , GetProcAddress } ,
23
- winnt:: {
24
- ACCESS_MASK , BOOLEAN , GENERIC_READ , GENERIC_WRITE , HANDLE , LARGE_INTEGER , LPCSTR ,
25
- PHANDLE , PLARGE_INTEGER , PVOID ,
26
- } ,
15
+
16
+ use windows_sys:: Win32 :: {
17
+ Foundation :: { CloseHandle , BOOLEAN , HANDLE , NTSTATUS , STATUS_SUCCESS , STATUS_TIMEOUT } ,
18
+ System :: {
19
+ LibraryLoader :: { GetModuleHandleA , GetProcAddress } ,
20
+ SystemServices :: { GENERIC_READ , GENERIC_WRITE } ,
27
21
} ,
28
22
} ;
29
23
@@ -36,58 +30,49 @@ pub struct KeyedEvent {
36
30
handle : HANDLE ,
37
31
NtReleaseKeyedEvent : extern "system" fn (
38
32
EventHandle : HANDLE ,
39
- Key : PVOID ,
33
+ Key : * mut ffi :: c_void ,
40
34
Alertable : BOOLEAN ,
41
- Timeout : PLARGE_INTEGER ,
35
+ Timeout : * mut i64 ,
42
36
) -> NTSTATUS ,
43
37
NtWaitForKeyedEvent : extern "system" fn (
44
38
EventHandle : HANDLE ,
45
- Key : PVOID ,
39
+ Key : * mut ffi :: c_void ,
46
40
Alertable : BOOLEAN ,
47
- Timeout : PLARGE_INTEGER ,
41
+ Timeout : * mut i64 ,
48
42
) -> NTSTATUS ,
49
43
}
50
44
51
45
impl KeyedEvent {
52
46
#[ inline]
53
- unsafe fn wait_for ( & self , key : PVOID , timeout : PLARGE_INTEGER ) -> NTSTATUS {
54
- ( self . NtWaitForKeyedEvent ) ( self . handle , key, 0 , timeout)
47
+ unsafe fn wait_for ( & self , key : * mut ffi :: c_void , timeout : * mut i64 ) -> NTSTATUS {
48
+ ( self . NtWaitForKeyedEvent ) ( self . handle , key, false . into ( ) , timeout)
55
49
}
56
50
57
51
#[ inline]
58
- unsafe fn release ( & self , key : PVOID ) -> NTSTATUS {
59
- ( self . NtReleaseKeyedEvent ) ( self . handle , key, 0 , ptr:: null_mut ( ) )
52
+ unsafe fn release ( & self , key : * mut ffi :: c_void ) -> NTSTATUS {
53
+ ( self . NtReleaseKeyedEvent ) ( self . handle , key, false . into ( ) , ptr:: null_mut ( ) )
60
54
}
61
55
62
56
#[ allow( non_snake_case) ]
63
57
pub fn create ( ) -> Option < KeyedEvent > {
64
58
unsafe {
65
- let ntdll = GetModuleHandleA ( b"ntdll.dll\0 " . as_ptr ( ) as LPCSTR ) ;
66
- if ntdll. is_null ( ) {
59
+ let ntdll = GetModuleHandleA ( b"ntdll.dll\0 " . as_ptr ( ) as * mut u8 ) ;
60
+ if ntdll == 0 {
67
61
return None ;
68
62
}
69
63
70
64
let NtCreateKeyedEvent =
71
- GetProcAddress ( ntdll, b"NtCreateKeyedEvent\0 " . as_ptr ( ) as LPCSTR ) ;
72
- if NtCreateKeyedEvent . is_null ( ) {
73
- return None ;
74
- }
65
+ GetProcAddress ( ntdll, b"NtCreateKeyedEvent\0 " . as_ptr ( ) as * mut u8 ) ?;
75
66
let NtReleaseKeyedEvent =
76
- GetProcAddress ( ntdll, b"NtReleaseKeyedEvent\0 " . as_ptr ( ) as LPCSTR ) ;
77
- if NtReleaseKeyedEvent . is_null ( ) {
78
- return None ;
79
- }
67
+ GetProcAddress ( ntdll, b"NtReleaseKeyedEvent\0 " . as_ptr ( ) as * mut u8 ) ?;
80
68
let NtWaitForKeyedEvent =
81
- GetProcAddress ( ntdll, b"NtWaitForKeyedEvent\0 " . as_ptr ( ) as LPCSTR ) ;
82
- if NtWaitForKeyedEvent . is_null ( ) {
83
- return None ;
84
- }
69
+ GetProcAddress ( ntdll, b"NtWaitForKeyedEvent\0 " . as_ptr ( ) as * mut u8 ) ?;
85
70
86
71
let NtCreateKeyedEvent : extern "system" fn (
87
- KeyedEventHandle : PHANDLE ,
88
- DesiredAccess : ACCESS_MASK ,
89
- ObjectAttributes : PVOID ,
90
- Flags : ULONG ,
72
+ KeyedEventHandle : * mut HANDLE ,
73
+ DesiredAccess : u32 ,
74
+ ObjectAttributes : * mut ffi :: c_void ,
75
+ Flags : u32 ,
91
76
) -> NTSTATUS = mem:: transmute ( NtCreateKeyedEvent ) ;
92
77
let mut handle = MaybeUninit :: uninit ( ) ;
93
78
let status = NtCreateKeyedEvent (
@@ -120,7 +105,7 @@ impl KeyedEvent {
120
105
121
106
#[ inline]
122
107
pub unsafe fn park ( & ' static self , key : & AtomicUsize ) {
123
- let status = self . wait_for ( key as * const _ as PVOID , ptr:: null_mut ( ) ) ;
108
+ let status = self . wait_for ( key as * const _ as * mut ffi :: c_void , ptr:: null_mut ( ) ) ;
124
109
debug_assert_eq ! ( status, STATUS_SUCCESS ) ;
125
110
}
126
111
@@ -140,22 +125,21 @@ impl KeyedEvent {
140
125
141
126
// NT uses a timeout in units of 100ns. We use a negative value to
142
127
// indicate a relative timeout based on a monotonic clock.
143
- let mut nt_timeout: LARGE_INTEGER = mem:: zeroed ( ) ;
144
128
let diff = timeout - now;
145
129
let value = ( diff. as_secs ( ) as i64 )
146
130
. checked_mul ( -10000000 )
147
131
. and_then ( |x| x. checked_sub ( ( diff. subsec_nanos ( ) as i64 + 99 ) / 100 ) ) ;
148
132
149
- match value {
150
- Some ( x) => * nt_timeout . QuadPart_mut ( ) = x,
133
+ let mut nt_timeout = match value {
134
+ Some ( x) => x,
151
135
None => {
152
136
// Timeout overflowed, just sleep indefinitely
153
137
self . park ( key) ;
154
138
return true ;
155
139
}
156
140
} ;
157
141
158
- let status = self . wait_for ( key as * const _ as PVOID , & mut nt_timeout) ;
142
+ let status = self . wait_for ( key as * const _ as * mut ffi :: c_void , & mut nt_timeout) ;
159
143
if status == STATUS_SUCCESS {
160
144
return true ;
161
145
}
@@ -192,7 +176,7 @@ impl Drop for KeyedEvent {
192
176
fn drop ( & mut self ) {
193
177
unsafe {
194
178
let ok = CloseHandle ( self . handle ) ;
195
- debug_assert_eq ! ( ok, TRUE ) ;
179
+ debug_assert_eq ! ( ok, true . into ( ) ) ;
196
180
}
197
181
}
198
182
}
@@ -211,7 +195,7 @@ impl UnparkHandle {
211
195
#[ inline]
212
196
pub unsafe fn unpark ( self ) {
213
197
if !self . key . is_null ( ) {
214
- let status = self . keyed_event . release ( self . key as PVOID ) ;
198
+ let status = self . keyed_event . release ( self . key as * mut ffi :: c_void ) ;
215
199
debug_assert_eq ! ( status, STATUS_SUCCESS ) ;
216
200
}
217
201
}
0 commit comments