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(!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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue