ntdll: Implement [Rtl]Create/DeleteTimerQueue[Ex].

oldstable
Dan Hipschman 2008-07-21 17:46:30 -07:00 committed by Alexandre Julliard
parent 09f4ca64e2
commit 20a1ca2bbf
5 changed files with 97 additions and 18 deletions

View File

@ -1047,9 +1047,16 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle )
*/
HANDLE WINAPI CreateTimerQueue(void)
{
FIXME("stub\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
HANDLE q;
NTSTATUS status = RtlCreateTimerQueue(&q);
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return NULL;
}
return q;
}
@ -1058,9 +1065,15 @@ HANDLE WINAPI CreateTimerQueue(void)
*/
BOOL WINAPI DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
{
FIXME("(%p, %p): stub\n", TimerQueue, CompletionEvent);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
NTSTATUS status = RtlDeleteTimerQueueEx(TimerQueue, CompletionEvent);
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
return TRUE;
}
/***********************************************************************

View File

@ -605,18 +605,15 @@ static void test_timer_queue(void)
/* Test asynchronous deletion of the queue. */
q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n");
SetLastError(0xdeadbeef);
ret = pDeleteTimerQueueEx(q, NULL);
ok(!ret, "DeleteTimerQueueEx\n");
todo_wine
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
/* Test synchronous deletion of the queue and running timers. */
q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n");
/* Called once. */
@ -668,9 +665,9 @@ static void test_timer_queue(void)
Sleep(500);
ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
ok(ret, "DeleteTimerQueueEx\n");
todo_wine
{
ok(ret, "DeleteTimerQueueEx\n");
ok(n1 == 1, "Timer callback 1\n");
ok(n2 < n3, "Timer callback 2 should be much slower than 3\n");
}
@ -687,23 +684,18 @@ static void test_timer_queue(void)
}
q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n");
SetLastError(0xdeadbeef);
ret = pDeleteTimerQueueEx(q, e);
ok(!ret, "DeleteTimerQueueEx\n");
todo_wine
{
ok(GetLastError() == ERROR_IO_PENDING, "DeleteTimerQueueEx\n");
ok(WaitForSingleObject(e, 250) == WAIT_OBJECT_0,
"Timer destruction event not triggered\n");
}
CloseHandle(e);
/* Test deleting/changing a timer in execution. */
q = pCreateTimerQueue();
todo_wine
ok(q != NULL, "CreateTimerQueue\n");
d2.t = t2 = NULL;
@ -731,9 +723,9 @@ static void test_timer_queue(void)
Sleep(200);
ret = pDeleteTimerQueueEx(q, INVALID_HANDLE_VALUE);
ok(ret, "DeleteTimerQueueEx\n");
todo_wine
{
ok(ret, "DeleteTimerQueueEx\n");
ok(d2.num_calls == d2.max_calls, "DeleteTimerQueueTimer\n");
ok(d3.num_calls == d3.max_calls, "ChangeTimerQueueTimer\n");
}

View File

@ -489,7 +489,7 @@
# @ stub RtlCreateSystemVolumeInformationFolder
@ stub RtlCreateTagHeap
# @ stub RtlCreateTimer
# @ stub RtlCreateTimerQueue
@ stdcall RtlCreateTimerQueue(ptr)
@ stdcall RtlCreateUnicodeString(ptr wstr)
@ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str)
@ stub RtlCreateUserProcess
@ -520,7 +520,7 @@
@ stdcall RtlDeleteSecurityObject(ptr)
# @ stub RtlDeleteTimer
# @ stub RtlDeleteTimerQueue
# @ stub RtlDeleteTimerQueueEx
@ stdcall RtlDeleteTimerQueueEx(ptr ptr)
@ stdcall RtlDeregisterWait(ptr)
@ stdcall RtlDeregisterWaitEx(ptr ptr)
@ stdcall RtlDestroyAtomTable(ptr)

View File

@ -528,3 +528,75 @@ NTSTATUS WINAPI RtlDeregisterWait(HANDLE WaitHandle)
{
return RtlDeregisterWaitEx(WaitHandle, NULL);
}
/************************** Timer Queue Impl **************************/
struct queue_timer
{
struct list entry;
};
struct timer_queue
{
RTL_CRITICAL_SECTION cs;
struct list timers;
};
/***********************************************************************
* RtlCreateTimerQueue (NTDLL.@)
*
* Creates a timer queue object and returns a handle to it.
*
* PARAMS
* NewTimerQueue [O] The newly created queue.
*
* RETURNS
* Success: STATUS_SUCCESS.
* Failure: Any NTSTATUS code.
*/
NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE NewTimerQueue)
{
struct timer_queue *q = RtlAllocateHeap(GetProcessHeap(), 0, sizeof *q);
if (!q)
return STATUS_NO_MEMORY;
RtlInitializeCriticalSection(&q->cs);
list_init(&q->timers);
*NewTimerQueue = q;
return STATUS_SUCCESS;
}
/***********************************************************************
* RtlDeleteTimerQueueEx (NTDLL.@)
*
* Deletes a timer queue object.
*
* PARAMS
* TimerQueue [I] The timer queue to destroy.
* CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE,
* wait until all timers are finished firing before
* returning. Otherwise, return immediately and set the
* event when all timers are done.
*
* RETURNS
* Success: STATUS_SUCCESS if synchronous, STATUS_PENDING if not.
* Failure: Any NTSTATUS code.
*/
NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
{
struct timer_queue *q = TimerQueue;
RtlDeleteCriticalSection(&q->cs);
RtlFreeHeap(GetProcessHeap(), 0, q);
if (CompletionEvent == INVALID_HANDLE_VALUE)
return STATUS_SUCCESS;
else
{
if (CompletionEvent)
NtSetEvent(CompletionEvent, NULL);
return STATUS_PENDING;
}
}

View File

@ -2117,6 +2117,7 @@ NTSYSAPI NTSTATUS WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*);
NTSYSAPI HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,SIZE_T,SIZE_T,PVOID,PRTL_HEAP_DEFINITION);
NTSYSAPI NTSTATUS WINAPI RtlCreateProcessParameters(RTL_USER_PROCESS_PARAMETERS**,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,PWSTR,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*,const UNICODE_STRING*);
NTSYSAPI NTSTATUS WINAPI RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD);
NTSYSAPI NTSTATUS WINAPI RtlCreateTimerQueue(PHANDLE);
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR);
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
@ -2127,6 +2128,7 @@ NTSYSAPI NTSTATUS WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *);
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR);
NTSYSAPI void WINAPI RtlDeleteResource(LPRTL_RWLOCK);
NTSYSAPI NTSTATUS WINAPI RtlDeleteSecurityObject(PSECURITY_DESCRIPTOR*);
NTSYSAPI NTSTATUS WINAPI RtlDeleteTimerQueueEx(HANDLE, HANDLE);
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*);
NTSYSAPI NTSTATUS WINAPI RtlDeregisterWait(HANDLE);
NTSYSAPI NTSTATUS WINAPI RtlDeregisterWaitEx(HANDLE,HANDLE);