Commit a148e190 authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

ntdll: Add support for a default timer queue.

parent c7da79de
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment