ntdll: Add support for a default timer queue.
This commit is contained in:
parent
c7da79ded3
commit
a148e190af
|
@ -880,6 +880,20 @@ static void test_timer_queue(void)
|
|||
ok(!ret, "DeleteTimerQueueEx\n");
|
||||
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
|
||||
ok(d1.num_calls == 1, "DeleteTimerQueueTimer\n");
|
||||
|
||||
/* Test functions on the default timer queue. */
|
||||
t1 = NULL;
|
||||
n1 = 0;
|
||||
ret = pCreateTimerQueueTimer(&t1, NULL, timer_queue_cb1, &n1, 1000,
|
||||
1000, 0);
|
||||
ok(ret, "CreateTimerQueueTimer, default queue\n");
|
||||
ok(t1 != NULL, "CreateTimerQueueTimer, default queue\n");
|
||||
|
||||
ret = pChangeTimerQueueTimer(NULL, t1, 2000, 2000);
|
||||
ok(ret, "ChangeTimerQueueTimer, default queue\n");
|
||||
|
||||
ret = pDeleteTimerQueueTimer(NULL, t1, INVALID_HANDLE_VALUE);
|
||||
ok(ret, "DeleteTimerQueueTimer, default queue\n");
|
||||
}
|
||||
|
||||
START_TEST(sync)
|
||||
|
|
|
@ -816,9 +816,14 @@ NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
|
|||
{
|
||||
struct timer_queue *q = TimerQueue;
|
||||
struct queue_timer *t, *temp;
|
||||
HANDLE thread = q->thread;
|
||||
HANDLE thread;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!q)
|
||||
return STATUS_INVALID_HANDLE;
|
||||
|
||||
thread = q->thread;
|
||||
|
||||
RtlEnterCriticalSection(&q->cs);
|
||||
q->quit = TRUE;
|
||||
if (list_head(&q->timers))
|
||||
|
@ -851,6 +856,31 @@ NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
|
|||
return status;
|
||||
}
|
||||
|
||||
static struct timer_queue *default_timer_queue;
|
||||
|
||||
static struct timer_queue *get_timer_queue(HANDLE TimerQueue)
|
||||
{
|
||||
if (TimerQueue)
|
||||
return TimerQueue;
|
||||
else
|
||||
{
|
||||
if (!default_timer_queue)
|
||||
{
|
||||
HANDLE q;
|
||||
NTSTATUS status = RtlCreateTimerQueue(&q);
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
PVOID p = interlocked_cmpxchg_ptr(
|
||||
(void **) &default_timer_queue, q, NULL);
|
||||
if (p)
|
||||
/* Got beat to the punch. */
|
||||
RtlDeleteTimerQueueEx(p, NULL);
|
||||
}
|
||||
}
|
||||
return default_timer_queue;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RtlCreateTimer (NTDLL.@)
|
||||
*
|
||||
|
@ -882,8 +912,12 @@ NTSTATUS WINAPI RtlCreateTimer(PHANDLE NewTimer, HANDLE TimerQueue,
|
|||
ULONG Flags)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct timer_queue *q = TimerQueue;
|
||||
struct queue_timer *t = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *t);
|
||||
struct queue_timer *t;
|
||||
struct timer_queue *q = get_timer_queue(TimerQueue);
|
||||
if (!q)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
t = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *t);
|
||||
if (!t)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
|
@ -933,8 +967,8 @@ NTSTATUS WINAPI RtlCreateTimer(PHANDLE NewTimer, HANDLE TimerQueue,
|
|||
NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer,
|
||||
DWORD DueTime, DWORD Period)
|
||||
{
|
||||
struct timer_queue *q = TimerQueue;
|
||||
struct queue_timer *t = Timer;
|
||||
struct timer_queue *q = t->q;
|
||||
|
||||
RtlEnterCriticalSection(&q->cs);
|
||||
/* Can't change a timer if it was once-only or destroyed. */
|
||||
|
@ -969,8 +1003,8 @@ NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer,
|
|||
NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer,
|
||||
HANDLE CompletionEvent)
|
||||
{
|
||||
struct timer_queue *q = TimerQueue;
|
||||
struct queue_timer *t = Timer;
|
||||
struct timer_queue *q = t->q;
|
||||
NTSTATUS status = STATUS_PENDING;
|
||||
HANDLE event = NULL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue