Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4c64d0cd
Commit
4c64d0cd
authored
Jul 24, 2008
by
Dan Hipschman
Committed by
Alexandre Julliard
Jul 25, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement RtlDeleteTimer for kernel32's DeleteTimerQueueTimer.
parent
396e47ef
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
139 additions
and
16 deletions
+139
-16
sync.c
dlls/kernel32/sync.c
+6
-5
sync.c
dlls/kernel32/tests/sync.c
+79
-10
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-1
threadpool.c
dlls/ntdll/threadpool.c
+52
-0
winternl.h
include/winternl.h
+1
-0
No files found.
dlls/kernel32/sync.c
View file @
4c64d0cd
...
...
@@ -1131,15 +1131,16 @@ BOOL WINAPI ChangeTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer,
*
* RETURNS
* nonzero on success or zero on failure
*
* BUGS
* Unimplemented
*/
BOOL
WINAPI
DeleteTimerQueueTimer
(
HANDLE
TimerQueue
,
HANDLE
Timer
,
HANDLE
CompletionEvent
)
{
FIXME
(
"stub
\n
"
);
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
NTSTATUS
status
=
RtlDeleteTimer
(
TimerQueue
,
Timer
,
CompletionEvent
);
if
(
status
!=
STATUS_SUCCESS
)
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
FALSE
;
}
return
TRUE
;
}
...
...
dlls/kernel32/tests/sync.c
View file @
4c64d0cd
...
...
@@ -566,11 +566,8 @@ static void CALLBACK timer_queue_cb2(PVOID p, BOOLEAN timedOut)
/* Note, XP SP2 does *not* do any deadlock checking, so passing
INVALID_HANDLE_VALUE here will just hang. */
ret
=
pDeleteTimerQueueTimer
(
d
->
q
,
d
->
t
,
NULL
);
todo_wine
{
ok
(
!
ret
,
"DeleteTimerQueueTimer
\n
"
);
ok
(
GetLastError
()
==
ERROR_IO_PENDING
,
"DeleteTimerQueueTimer
\n
"
);
}
}
}
...
...
@@ -604,12 +601,20 @@ static void CALLBACK timer_queue_cb4(PVOID p, BOOLEAN timedOut)
}
}
static
void
CALLBACK
timer_queue_cb5
(
PVOID
p
,
BOOLEAN
timedOut
)
{
DWORD
delay
=
(
DWORD
)
p
;
ok
(
timedOut
,
"Timer callbacks should always time out
\n
"
);
if
(
delay
)
Sleep
(
delay
);
}
static
void
test_timer_queue
(
void
)
{
HANDLE
q
,
t1
,
t2
,
t3
,
t4
,
t5
;
int
n1
,
n2
,
n3
,
n4
,
n5
;
struct
timer_queue_data1
d2
,
d3
,
d4
;
HANDLE
e
;
HANDLE
e
,
et1
,
et2
;
BOOL
ret
;
if
(
!
pChangeTimerQueueTimer
||
!
pCreateTimerQueue
||
!
pCreateTimerQueueTimer
...
...
@@ -675,6 +680,14 @@ static void test_timer_queue(void)
/* Give them a chance to do some work. */
Sleep
(
500
);
/* Test deleting a once-only timer. */
ret
=
pDeleteTimerQueueTimer
(
q
,
t1
,
INVALID_HANDLE_VALUE
);
ok
(
ret
,
"DeleteTimerQueueTimer
\n
"
);
/* A periodic timer. */
ret
=
pDeleteTimerQueueTimer
(
q
,
t2
,
INVALID_HANDLE_VALUE
);
ok
(
ret
,
"DeleteTimerQueueTimer
\n
"
);
ret
=
pDeleteTimerQueueEx
(
q
,
INVALID_HANDLE_VALUE
);
ok
(
ret
,
"DeleteTimerQueueEx
\n
"
);
ok
(
n1
==
1
,
"Timer callback 1
\n
"
);
...
...
@@ -682,9 +695,11 @@ static void test_timer_queue(void)
ok
(
n4
==
0
,
"Timer callback 4
\n
"
);
ok
(
n5
==
1
,
"Timer callback 5
\n
"
);
/* Test synchronous deletion of the queue with event trigger. */
/* Test synchronous deletion of the
timer/
queue with event trigger. */
e
=
CreateEvent
(
NULL
,
TRUE
,
FALSE
,
NULL
);
if
(
!
e
)
et1
=
CreateEvent
(
NULL
,
TRUE
,
FALSE
,
NULL
);
et2
=
CreateEvent
(
NULL
,
TRUE
,
FALSE
,
NULL
);
if
(
!
e
||
!
et1
||
!
et2
)
{
skip
(
"Failed to create timer queue descruction event
\n
"
);
return
;
...
...
@@ -693,12 +708,69 @@ static void test_timer_queue(void)
q
=
pCreateTimerQueue
();
ok
(
q
!=
NULL
,
"CreateTimerQueue
\n
"
);
/* Run once and finish quickly (should be done when we delete it). */
t1
=
NULL
;
ret
=
pCreateTimerQueueTimer
(
&
t1
,
q
,
timer_queue_cb5
,
(
PVOID
)
0
,
0
,
0
,
0
);
ok
(
ret
,
"CreateTimerQueueTimer
\n
"
);
ok
(
t1
!=
NULL
,
"CreateTimerQueueTimer
\n
"
);
/* Run once and finish slowly (shouldn't be done when we delete it). */
t2
=
NULL
;
ret
=
pCreateTimerQueueTimer
(
&
t2
,
q
,
timer_queue_cb5
,
(
PVOID
)
1000
,
0
,
0
,
0
);
ok
(
ret
,
"CreateTimerQueueTimer
\n
"
);
ok
(
t2
!=
NULL
,
"CreateTimerQueueTimer
\n
"
);
/* Run once and finish quickly (should be done when we delete it). */
t3
=
NULL
;
ret
=
pCreateTimerQueueTimer
(
&
t3
,
q
,
timer_queue_cb5
,
(
PVOID
)
0
,
0
,
0
,
0
);
ok
(
ret
,
"CreateTimerQueueTimer
\n
"
);
ok
(
t3
!=
NULL
,
"CreateTimerQueueTimer
\n
"
);
/* Run once and finish slowly (shouldn't be done when we delete it). */
t4
=
NULL
;
ret
=
pCreateTimerQueueTimer
(
&
t4
,
q
,
timer_queue_cb5
,
(
PVOID
)
1000
,
0
,
0
,
0
);
ok
(
ret
,
"CreateTimerQueueTimer
\n
"
);
ok
(
t4
!=
NULL
,
"CreateTimerQueueTimer
\n
"
);
/* Give them a chance to start. */
Sleep
(
400
);
/* DeleteTimerQueueTimer always returns PENDING with a NULL event,
even if the timer is finished. */
SetLastError
(
0xdeadbeef
);
ret
=
pDeleteTimerQueueTimer
(
q
,
t1
,
NULL
);
ok
(
!
ret
,
"DeleteTimerQueueTimer
\n
"
);
ok
(
GetLastError
()
==
ERROR_IO_PENDING
,
"DeleteTimerQueueTimer
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
pDeleteTimerQueueTimer
(
q
,
t2
,
NULL
);
ok
(
!
ret
,
"DeleteTimerQueueTimer
\n
"
);
ok
(
GetLastError
()
==
ERROR_IO_PENDING
,
"DeleteTimerQueueTimer
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
pDeleteTimerQueueTimer
(
q
,
t3
,
et1
);
ok
(
ret
,
"DeleteTimerQueueTimer
\n
"
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"DeleteTimerQueueTimer
\n
"
);
ok
(
WaitForSingleObject
(
et1
,
250
)
==
WAIT_OBJECT_0
,
"Timer destruction event not triggered
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
pDeleteTimerQueueTimer
(
q
,
t4
,
et2
);
ok
(
!
ret
,
"DeleteTimerQueueTimer
\n
"
);
ok
(
GetLastError
()
==
ERROR_IO_PENDING
,
"DeleteTimerQueueTimer
\n
"
);
ok
(
WaitForSingleObject
(
et2
,
1000
)
==
WAIT_OBJECT_0
,
"Timer destruction event not triggered
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
pDeleteTimerQueueEx
(
q
,
e
);
ok
(
!
ret
,
"DeleteTimerQueueEx
\n
"
);
ok
(
GetLastError
()
==
ERROR_IO_PENDING
,
"DeleteTimerQueueEx
\n
"
);
ok
(
WaitForSingleObject
(
e
,
250
)
==
WAIT_OBJECT_0
,
"
Timer
destruction event not triggered
\n
"
);
"
Queue
destruction event not triggered
\n
"
);
CloseHandle
(
e
);
/* Test deleting/changing a timer in execution. */
...
...
@@ -749,10 +821,7 @@ static void test_timer_queue(void)
ret
=
pDeleteTimerQueueEx
(
q
,
INVALID_HANDLE_VALUE
);
ok
(
ret
,
"DeleteTimerQueueEx
\n
"
);
ok
(
n1
==
1
,
"ChangeTimerQueueTimer
\n
"
);
todo_wine
{
ok
(
d2
.
num_calls
==
d2
.
max_calls
,
"DeleteTimerQueueTimer
\n
"
);
}
ok
(
d3
.
num_calls
==
d3
.
max_calls
,
"ChangeTimerQueueTimer
\n
"
);
ok
(
d4
.
num_calls
==
1
,
"Timer flagged for deletion incorrectly
\n
"
);
}
...
...
dlls/ntdll/ntdll.spec
View file @
4c64d0cd
...
...
@@ -518,7 +518,7 @@
@ stdcall RtlDeleteRegistryValue(long ptr ptr)
@ stdcall RtlDeleteResource(ptr)
@ stdcall RtlDeleteSecurityObject(ptr)
# @ stub RtlDeleteTimer
@ stdcall RtlDeleteTimer(ptr ptr ptr)
# @ stub RtlDeleteTimerQueue
@ stdcall RtlDeleteTimerQueueEx(ptr ptr)
@ stdcall RtlDeregisterWait(ptr)
...
...
dlls/ntdll/threadpool.c
View file @
4c64d0cd
...
...
@@ -545,6 +545,7 @@ struct queue_timer
ULONG
flags
;
ULONGLONG
expire
;
BOOL
destroy
;
/* timer should be deleted; once set, never unset */
HANDLE
event
;
/* removal event */
};
struct
timer_queue
...
...
@@ -569,6 +570,8 @@ static void queue_remove_timer(struct queue_timer *t)
assert
(
t
->
destroy
);
list_remove
(
&
t
->
entry
);
if
(
t
->
event
)
NtSetEvent
(
t
->
event
,
NULL
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
t
);
if
(
q
->
quit
&&
list_count
(
&
q
->
timers
)
==
0
)
...
...
@@ -891,6 +894,7 @@ NTSTATUS WINAPI RtlCreateTimer(PHANDLE NewTimer, HANDLE TimerQueue,
t
->
period
=
Period
;
t
->
flags
=
Flags
;
t
->
destroy
=
FALSE
;
t
->
event
=
NULL
;
status
=
STATUS_SUCCESS
;
RtlEnterCriticalSection
(
&
q
->
cs
);
...
...
@@ -943,3 +947,51 @@ NTSTATUS WINAPI RtlUpdateTimer(HANDLE TimerQueue, HANDLE Timer,
return
STATUS_SUCCESS
;
}
/***********************************************************************
* RtlDeleteTimer (NTDLL.@)
*
* Cancels a timer-queue timer.
*
* PARAMS
* TimerQueue [I] The queue that holds the timer.
* Timer [I] The timer to update.
* CompletionEvent [I] If NULL, return immediately. If INVALID_HANDLE_VALUE,
* wait until the timer is finished firing all pending
* callbacks before returning. Otherwise, return
* immediately and set the timer is done.
*
* RETURNS
* Success: STATUS_SUCCESS if the timer is done, STATUS_PENDING if not,
or if the completion event is NULL.
* Failure: Any NTSTATUS code.
*/
NTSTATUS
WINAPI
RtlDeleteTimer
(
HANDLE
TimerQueue
,
HANDLE
Timer
,
HANDLE
CompletionEvent
)
{
struct
timer_queue
*
q
=
TimerQueue
;
struct
queue_timer
*
t
=
Timer
;
NTSTATUS
status
=
STATUS_PENDING
;
HANDLE
event
=
NULL
;
if
(
CompletionEvent
==
INVALID_HANDLE_VALUE
)
status
=
NtCreateEvent
(
&
event
,
EVENT_ALL_ACCESS
,
NULL
,
FALSE
,
FALSE
);
else
if
(
CompletionEvent
)
event
=
CompletionEvent
;
RtlEnterCriticalSection
(
&
q
->
cs
);
t
->
event
=
event
;
if
(
t
->
runcount
==
0
&&
event
)
status
=
STATUS_SUCCESS
;
queue_destroy_timer
(
t
);
RtlLeaveCriticalSection
(
&
q
->
cs
);
if
(
CompletionEvent
==
INVALID_HANDLE_VALUE
&&
event
)
{
if
(
status
==
STATUS_PENDING
)
NtWaitForSingleObject
(
event
,
FALSE
,
NULL
);
NtClose
(
event
);
}
return
status
;
}
include/winternl.h
View file @
4c64d0cd
...
...
@@ -2129,6 +2129,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
RtlDeleteTimer
(
HANDLE
,
HANDLE
,
HANDLE
);
NTSYSAPI
NTSTATUS
WINAPI
RtlDeleteTimerQueueEx
(
HANDLE
,
HANDLE
);
NTSYSAPI
PRTL_USER_PROCESS_PARAMETERS
WINAPI
RtlDeNormalizeProcessParams
(
RTL_USER_PROCESS_PARAMETERS
*
);
NTSYSAPI
NTSTATUS
WINAPI
RtlDeregisterWait
(
HANDLE
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment