ntdll: Add support for a default timer queue.

This commit is contained in:
Dan Hipschman 2008-07-29 14:36:41 -07:00 committed by Alexandre Julliard
parent c7da79ded3
commit a148e190af
2 changed files with 53 additions and 5 deletions

View File

@ -880,6 +880,20 @@ static void test_timer_queue(void)
ok(!ret, "DeleteTimerQueueEx\n"); ok(!ret, "DeleteTimerQueueEx\n");
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n"); ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
ok(d1.num_calls == 1, "DeleteTimerQueueTimer\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) START_TEST(sync)

View File

@ -816,9 +816,14 @@ NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
{ {
struct timer_queue *q = TimerQueue; struct timer_queue *q = TimerQueue;
struct queue_timer *t, *temp; struct queue_timer *t, *temp;
HANDLE thread = q->thread; HANDLE thread;
NTSTATUS status; NTSTATUS status;
if (!q)
return STATUS_INVALID_HANDLE;
thread = q->thread;
RtlEnterCriticalSection(&q->cs); RtlEnterCriticalSection(&q->cs);
q->quit = TRUE; q->quit = TRUE;
if (list_head(&q->timers)) if (list_head(&q->timers))
@ -851,6 +856,31 @@ NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
return status; 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.@) * RtlCreateTimer (NTDLL.@)
* *
@ -882,8 +912,12 @@ NTSTATUS WINAPI RtlCreateTimer(PHANDLE NewTimer, HANDLE TimerQueue,
ULONG Flags) ULONG Flags)
{ {
NTSTATUS status; NTSTATUS status;
struct timer_queue *q = TimerQueue; struct queue_timer *t;
struct queue_timer *t = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *t); struct timer_queue *q = get_timer_queue(TimerQueue);
if (!q)
return STATUS_NO_MEMORY;
t = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *t);
if (!t) if (!t)
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
@ -933,8 +967,8 @@ NTSTATUS WINAPI RtlCreateTimer(PHANDLE NewTimer, HANDLE TimerQueue,
NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer, NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer,
DWORD DueTime, DWORD Period) DWORD DueTime, DWORD Period)
{ {
struct timer_queue *q = TimerQueue;
struct queue_timer *t = Timer; struct queue_timer *t = Timer;
struct timer_queue *q = t->q;
RtlEnterCriticalSection(&q->cs); RtlEnterCriticalSection(&q->cs);
/* Can't change a timer if it was once-only or destroyed. */ /* 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, NTSTATUS WINAPI RtlDeleteTimer(HANDLE TimerQueue, HANDLE Timer,
HANDLE CompletionEvent) HANDLE CompletionEvent)
{ {
struct timer_queue *q = TimerQueue;
struct queue_timer *t = Timer; struct queue_timer *t = Timer;
struct timer_queue *q = t->q;
NTSTATUS status = STATUS_PENDING; NTSTATUS status = STATUS_PENDING;
HANDLE event = NULL; HANDLE event = NULL;