2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/client/timerqueue.c
5 * PURPOSE: Timer Queue Functions
6 * PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
9 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 HANDLE BasepDefaultTimerQueue
= NULL
;
20 /* PRIVATE FUNCTIONS **********************************************************/
22 /* FIXME - make this thread safe */
25 BasepCreateDefaultTimerQueue(VOID
)
29 /* Create the timer queue */
30 Status
= RtlCreateTimerQueue(&BasepDefaultTimerQueue
);
31 if (!NT_SUCCESS(Status
))
33 BaseSetLastNTError(Status
);
34 DPRINT1("Unable to create the default timer queue!\n");
41 /* PUBLIC FUNCTIONS ***********************************************************/
49 CancelTimerQueueTimer(IN HANDLE TimerQueue
,
56 /* Use the default timer queue */
57 TimerQueue
= BasepDefaultTimerQueue
;
60 /* A timer is being cancelled before one was created... fail */
61 SetLastError(ERROR_INVALID_HANDLE
);
66 /* Delete the timer */
67 Status
= RtlDeleteTimer(TimerQueue
, Timer
, NULL
);
68 if (!NT_SUCCESS(Status
))
70 BaseSetLastNTError(Status
);
82 ChangeTimerQueueTimer(IN HANDLE TimerQueue
,
91 /* Use the default timer queue */
92 TimerQueue
= BasepDefaultTimerQueue
;
95 /* A timer is being cancelled before one was created... fail */
96 SetLastError(ERROR_INVALID_PARAMETER
);
101 /* Delete the timer */
102 Status
= RtlUpdateTimer(TimerQueue
, Timer
, DueTime
, Period
);
103 if (!NT_SUCCESS(Status
))
105 BaseSetLastNTError(Status
);
117 CreateTimerQueue(VOID
)
122 /* Create the timer queue */
123 Status
= RtlCreateTimerQueue(&Handle
);
124 if(!NT_SUCCESS(Status
))
126 BaseSetLastNTError(Status
);
138 CreateTimerQueueTimer(OUT PHANDLE phNewTimer
,
139 IN HANDLE TimerQueue
,
140 IN WAITORTIMERCALLBACK Callback
,
148 /* Parameter is not optional -- clear it now */
151 /* Check if no queue was given */
154 /* Create the queue if it didn't already exist */
155 if (!(BasepDefaultTimerQueue
) && !(BasepCreateDefaultTimerQueue()))
160 /* Use the default queue */
161 TimerQueue
= BasepDefaultTimerQueue
;
164 /* Create the timer. Note that no parameter checking is done here */
165 Status
= RtlCreateTimer(TimerQueue
,
172 if (!NT_SUCCESS(Status
))
174 BaseSetLastNTError(Status
);
186 DeleteTimerQueue(IN HANDLE TimerQueue
)
188 /* We don't allow the user to delete the default timer queue */
191 SetLastError(ERROR_INVALID_HANDLE
);
195 /* Delete the timer queue */
196 RtlDeleteTimerQueueEx(TimerQueue
, 0);
205 DeleteTimerQueueEx(IN HANDLE TimerQueue
,
206 IN HANDLE CompletionEvent
)
210 /* We don't allow the user to delete the default timer queue */
213 SetLastError(ERROR_INVALID_HANDLE
);
217 /* Delete the timer queue */
218 Status
= RtlDeleteTimerQueueEx(TimerQueue
, CompletionEvent
);
219 if (((CompletionEvent
!= INVALID_HANDLE_VALUE
) && (Status
== STATUS_PENDING
)) ||
220 !(NT_SUCCESS(Status
)))
222 /* In case CompletionEvent == NULL, RtlDeleteTimerQueueEx() returns before
223 all callback routines returned. We set the last error code to STATUS_PENDING
224 and return FALSE. In case CompletionEvent == INVALID_HANDLE_VALUE we only
225 can get here if another error occured. In case CompletionEvent is something
226 else, we get here and fail, even though it isn't really an error (if Status == STATUS_PENDING).
227 We also handle all other failures the same way. */
228 BaseSetLastNTError(Status
);
240 DeleteTimerQueueTimer(IN HANDLE TimerQueue
,
242 IN HANDLE CompletionEvent
)
248 /* Use the default timer queue */
249 TimerQueue
= BasepDefaultTimerQueue
;
252 /* A timer is being cancelled before one was created... fail */
253 SetLastError(ERROR_INVALID_PARAMETER
);
258 /* Delete the timer */
259 Status
= RtlDeleteTimer(TimerQueue
, Timer
, CompletionEvent
);
260 if (((CompletionEvent
!= INVALID_HANDLE_VALUE
) && (Status
== STATUS_PENDING
)) ||
261 !(NT_SUCCESS(Status
)))
263 /* In case CompletionEvent == NULL, RtlDeleteTimerQueueEx() returns before
264 all callback routines returned. We set the last error code to STATUS_PENDING
265 and return FALSE. In case CompletionEvent == INVALID_HANDLE_VALUE we only
266 can get here if another error occured. In case CompletionEvent is something
267 else, we get here and fail, even though it isn't really an error (if Status == STATUS_PENDING).
268 We also handle all other failures the same way. */
269 BaseSetLastNTError(Status
);
281 SetTimerQueueTimer(IN HANDLE TimerQueue
,
282 IN WAITORTIMERCALLBACK Callback
,
291 /* Check if no queue was given */
294 /* Create the queue if it didn't already exist */
295 if (!(BasepDefaultTimerQueue
) && !(BasepCreateDefaultTimerQueue()))
300 /* Use the default queue */
301 TimerQueue
= BasepDefaultTimerQueue
;
304 /* Create the timer */
305 Status
= RtlCreateTimer(TimerQueue
,
311 PreferIo
? WT_EXECUTEINIOTHREAD
: WT_EXECUTEDEFAULT
);
312 if (!NT_SUCCESS(Status
))
314 BaseSetLastNTError(Status
);