1use crate::sys::{
3 QueryPerformanceFrequency,
4 QueryPerformanceCounter,
5 LARGE_INTEGER,
6 CreateTimerQueue,
7 CreateTimerQueueTimer,
8 DeleteTimerQueueEx,
9 DeleteTimerQueueTimer,
10 ChangeTimerQueueTimer,
11 HANDLE,
12 INVALID_HANDLE_VALUE,
13 WT_EXECUTEINTIMERTHREAD,
14 WT_EXECUTEINPERSISTENTTHREAD,
15 WT_EXECUTELONGFUNCTION,
16 WT_EXECUTEONLYONCE,
17 WT_TRANSFER_IMPERSONATION,
18 WAITORTIMERCALLBACK,
19 c_int,
20 c_ulong,
21 c_void,
22};
23use crate::utils::{self, Result};
24
25use core::{ptr, mem};
26
27pub fn query_performance_frequency() -> Result<i64> {
32 let mut counter: LARGE_INTEGER = unsafe { mem::zeroed() };
33
34 unsafe {
35 match QueryPerformanceFrequency(&mut counter as *mut _) {
36 0 => Err(utils::get_last_error()),
37 _ => Ok(counter.QuadPart)
38 }
39 }
40}
41
42pub fn query_performance_counter() -> Result<i64> {
45 let mut counter: LARGE_INTEGER = unsafe { mem::zeroed() };
46
47 unsafe {
48 match QueryPerformanceCounter(&mut counter as *mut _) {
49 0 => Err(utils::get_last_error()),
50 _ => Ok(counter.QuadPart)
51 }
52 }
53}
54
55pub trait CompleteEvent {
57 #[doc(hidden)]
58 fn handle() -> HANDLE;
59}
60
61pub struct NoWait;
63impl CompleteEvent for NoWait {
64 fn handle() -> HANDLE {
65 ptr::null_mut()
66 }
67}
68
69pub struct Wait;
71impl CompleteEvent for Wait {
72 fn handle() -> HANDLE {
73 INVALID_HANDLE_VALUE
74 }
75}
76
77#[derive(Copy, Clone)]
78pub struct TimerFlags {
80 inner: c_ulong
81}
82
83pub const DEFAULT_TIMER_FLAGS: TimerFlags = TimerFlags {
85 inner: 0
86};
87
88impl TimerFlags {
89 pub fn new() -> Self {
91 DEFAULT_TIMER_FLAGS
92 }
93
94 pub fn on_timer_thread(mut self) -> Self {
98 self.inner |= WT_EXECUTEINTIMERTHREAD;
99 self
100 }
101
102 pub fn on_persist(mut self) -> Self {
107 self.inner |= WT_EXECUTEINPERSISTENTTHREAD;
108 self
109 }
110
111 pub fn long_fn(mut self) -> Self {
115 self.inner |= WT_EXECUTELONGFUNCTION;
116 self
117 }
118
119 pub fn only_once(mut self) -> Self {
123 self.inner |= WT_EXECUTEONLYONCE;
124 self
125 }
126
127 pub fn transfer_impersonation(mut self) -> Self {
133 self.inner |= WT_TRANSFER_IMPERSONATION;
134 self
135 }
136}
137
138pub struct TimerQueue {
147 handle: HANDLE
148}
149
150impl TimerQueue {
151 pub fn new() -> Result<Self> {
153 let handle = unsafe { CreateTimerQueue() };
154
155 match handle.is_null() {
156 true => Err(utils::get_last_error()),
157 false => Ok(Self { handle })
158 }
159 }
160
161 #[inline]
162 fn inner_delete<T: CompleteEvent>(&self) -> c_int {
163 match self.handle.is_null() {
164 true => 1,
165 false => unsafe { DeleteTimerQueueEx(self.handle, T::handle()) },
166 }
167 }
168
169 pub fn delete<T: CompleteEvent>(self, _event: T) -> Result<()> {
173 let result = match self.inner_delete::<T>() {
174 0 => Err(utils::get_last_error()),
175 _ => Ok(())
176 };
177
178 mem::forget(self);
179 result
180 }
181
182 pub fn timer(&self, cb: WAITORTIMERCALLBACK, param: *mut c_void, due_time: c_ulong, period: c_ulong, flags: TimerFlags) -> Result<QueueTimer> {
192 let mut timer: *mut c_void = ptr::null_mut();
193
194 match unsafe { CreateTimerQueueTimer(&mut timer as *mut _, self.handle, cb, param, due_time, period, flags.inner) } {
195 0 => Err(utils::get_last_error()),
196 _ => Ok(QueueTimer { queue: self.handle, inner: timer })
197 }
198 }
199}
200
201pub type CallbackType = WAITORTIMERCALLBACK;
203
204pub const DEFAULT_TIMER_QUEUE: TimerQueue = TimerQueue {
206 handle: ptr::null_mut()
207};
208
209impl Default for TimerQueue {
210 fn default() -> Self {
211 DEFAULT_TIMER_QUEUE
212 }
213}
214
215impl Drop for TimerQueue {
216 fn drop(&mut self) {
217 let _ = self.inner_delete::<NoWait>();
218 }
219}
220
221unsafe impl Send for TimerQueue {}
222unsafe impl Sync for TimerQueue {}
223
224pub struct QueueTimer {
230 queue: HANDLE,
231 inner: HANDLE,
232}
233
234impl QueueTimer {
235 #[inline]
236 fn inner_delete<T: CompleteEvent>(&self) -> c_int {
237 unsafe { DeleteTimerQueueTimer(self.queue, self.inner, T::handle()) }
238 }
239
240 pub unsafe fn cancel<T: CompleteEvent>(&self, _event: T) -> Result<()> {
244 match self.inner_delete::<T>() {
245 0 => Err(utils::get_last_error()),
246 _ => Ok(())
247 }
248 }
249
250 pub fn reset(&self, due_time: c_ulong, period: c_ulong) -> Result<()> {
255 match unsafe { ChangeTimerQueueTimer(self.queue, self.inner, due_time, period) } {
256 0 => Err(utils::get_last_error()),
257 _ => Ok(())
258 }
259 }
260
261 pub fn delete<T: CompleteEvent>(self, event: T) -> Result<()> {
263 let result = unsafe { self.cancel(event) };
264
265 mem::forget(self);
266 result
267 }
268}
269
270impl Drop for QueueTimer {
271 fn drop(&mut self) {
272 let _ = self.inner_delete::<NoWait>();
273 }
274}
275
276unsafe impl Send for QueueTimer {}
277unsafe impl Sync for QueueTimer {}