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
5690304c
Commit
5690304c
authored
Apr 17, 2013
by
Dmitry Timoshkov
Committed by
Alexandre Julliard
Apr 17, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Add a test to check event, thread, mutex and semaphore states during process termination.
parent
4e1bac56
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
110 additions
and
16 deletions
+110
-16
loader.c
dlls/kernel32/tests/loader.c
+110
-16
No files found.
dlls/kernel32/tests/loader.c
View file @
5690304c
...
...
@@ -1040,27 +1040,51 @@ nt4_is_broken:
}
#define MAX_COUNT 10
static
HANDLE
attached_thread
[
MAX_COUNT
],
stop_event
;
static
HANDLE
attached_thread
[
MAX_COUNT
],
stop_event
,
event
,
mutex
,
semaphore
;
static
DWORD
attached_thread_count
;
static
int
test_dll_phase
;
static
DWORD
WINAPI
thread_proc
(
void
*
param
)
static
DWORD
WINAPI
mutex_
thread_proc
(
void
*
param
)
{
DWORD
ret
;
ret
=
WaitForSingleObject
(
mutex
,
0
);
ok
(
ret
==
WAIT_OBJECT_0
,
"expected WAIT_OBJECT_0, got %#x
\n
"
,
ret
);
SetEvent
(
param
);
while
(
1
)
{
trace
(
"%04u: mutex_thread_proc: still alive
\n
"
,
GetCurrentThreadId
());
if
(
WaitForSingleObject
(
stop_event
,
50
)
!=
WAIT_TIMEOUT
)
break
;
}
trace
(
"%04u: mutex_thread_proc: exiting
\n
"
,
GetCurrentThreadId
());
return
196
;
}
static
DWORD
WINAPI
semaphore_thread_proc
(
void
*
param
)
{
DWORD
ret
;
ret
=
WaitForSingleObject
(
semaphore
,
0
);
ok
(
ret
==
WAIT_OBJECT_0
,
"expected WAIT_OBJECT_0, got %#x
\n
"
,
ret
);
SetEvent
(
param
);
while
(
1
)
{
trace
(
"%04u: thread_proc: still alive
\n
"
,
GetCurrentThreadId
());
trace
(
"%04u:
semaphore_
thread_proc: still alive
\n
"
,
GetCurrentThreadId
());
if
(
WaitForSingleObject
(
stop_event
,
50
)
!=
WAIT_TIMEOUT
)
break
;
}
trace
(
"%04u: thread_proc: exiting
\n
"
,
GetCurrentThreadId
());
trace
(
"%04u:
semaphore_
thread_proc: exiting
\n
"
,
GetCurrentThreadId
());
return
196
;
}
static
BOOL
WINAPI
dll_entry_point
(
HINSTANCE
hinst
,
DWORD
reason
,
LPVOID
param
)
{
BOOL
ret
;
DWORD
ret
;
switch
(
reason
)
{
...
...
@@ -1098,7 +1122,7 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
ok
(
!
ret
||
broken
(
ret
)
/* before Vista */
,
"RtlDllShutdownInProgress returned %d
\n
"
,
ret
);
}
ok
(
attached_thread_count
!=
0
,
"attached thread count should not be 0
\n
"
);
ok
(
attached_thread_count
==
2
,
"attached thread count should be 2
\n
"
);
for
(
i
=
0
;
i
<
attached_thread_count
;
i
++
)
{
...
...
@@ -1108,6 +1132,34 @@ static BOOL WINAPI dll_entry_point(HINSTANCE hinst, DWORD reason, LPVOID param)
ok
(
code
==
expected_code
,
"expected thread exit code %u, got %u
\n
"
,
expected_code
,
code
);
}
ret
=
WaitForSingleObject
(
event
,
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
mutex
,
0
);
if
(
expected_code
==
STILL_ACTIVE
)
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
else
ok
(
ret
==
WAIT_ABANDONED
,
"expected WAIT_ABANDONED, got %#x
\n
"
,
ret
);
/* semaphore is not abandoned on thread termination */
ret
=
WaitForSingleObject
(
semaphore
,
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
if
(
expected_code
==
STILL_ACTIVE
)
{
ret
=
WaitForSingleObject
(
attached_thread
[
0
],
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
attached_thread
[
1
],
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
}
else
{
ret
=
WaitForSingleObject
(
attached_thread
[
0
],
0
);
ok
(
ret
==
WAIT_OBJECT_0
,
"expected WAIT_OBJECT_0, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
attached_thread
[
1
],
0
);
ok
(
ret
==
WAIT_OBJECT_0
,
"expected WAIT_OBJECT_0, got %#x
\n
"
,
ret
);
}
if
(
test_dll_phase
==
2
)
{
trace
(
"dll: call ExitProcess()
\n
"
);
...
...
@@ -1150,12 +1202,24 @@ static void child_process(const char *dll_name, DWORD target_offset)
{
void
*
target
;
DWORD
ret
,
dummy
,
i
,
code
,
expected_code
;
HANDLE
file
,
thread
,
event
;
HANDLE
file
,
thread
;
HMODULE
hmod
;
NTSTATUS
status
;
trace
(
"phase %d: writing %p at %#x
\n
"
,
test_dll_phase
,
dll_entry_point
,
target_offset
);
SetLastError
(
0xdeadbeef
);
mutex
=
CreateMutex
(
NULL
,
FALSE
,
NULL
);
ok
(
mutex
!=
0
,
"CreateMutex error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
semaphore
=
CreateSemaphore
(
NULL
,
1
,
1
,
NULL
);
ok
(
semaphore
!=
0
,
"CreateSemaphore error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
event
=
CreateEvent
(
NULL
,
TRUE
,
FALSE
,
NULL
);
ok
(
event
!=
0
,
"CreateEvent error %d
\n
"
,
GetLastError
());
file
=
CreateFile
(
dll_name
,
GENERIC_READ
|
GENERIC_WRITE
,
0
,
NULL
,
OPEN_EXISTING
,
0
,
0
);
if
(
file
==
INVALID_HANDLE_VALUE
)
{
...
...
@@ -1174,14 +1238,11 @@ static void child_process(const char *dll_name, DWORD target_offset)
ok
(
hmod
!=
0
,
"LoadLibrary error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
event
=
CreateEvent
(
NULL
,
0
,
0
,
NULL
);
ok
(
event
!=
0
,
"CreateEvent error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
stop_event
=
CreateEvent
(
NULL
,
0
,
0
,
NULL
);
stop_event
=
CreateEvent
(
NULL
,
TRUE
,
FALSE
,
NULL
);
ok
(
stop_event
!=
0
,
"CreateEvent error %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
thread
=
CreateThread
(
NULL
,
0
,
thread_proc
,
event
,
0
,
&
dummy
);
thread
=
CreateThread
(
NULL
,
0
,
mutex_
thread_proc
,
event
,
0
,
&
dummy
);
ok
(
thread
!=
0
,
"CreateThread error %d
\n
"
,
GetLastError
());
WaitForSingleObject
(
event
,
3000
);
CloseHandle
(
thread
);
...
...
@@ -1189,15 +1250,15 @@ static void child_process(const char *dll_name, DWORD target_offset)
ResetEvent
(
event
);
SetLastError
(
0xdeadbeef
);
thread
=
CreateThread
(
NULL
,
0
,
thread_proc
,
event
,
0
,
&
dummy
);
thread
=
CreateThread
(
NULL
,
0
,
semaphore_
thread_proc
,
event
,
0
,
&
dummy
);
ok
(
thread
!=
0
,
"CreateThread error %d
\n
"
,
GetLastError
());
WaitForSingleObject
(
event
,
3000
);
CloseHandle
(
thread
);
CloseHandle
(
event
);
ResetEvent
(
event
);
Sleep
(
100
);
ok
(
attached_thread_count
!=
0
,
"attached thread count should not be 0
\n
"
);
ok
(
attached_thread_count
==
2
,
"attached thread count should be 2
\n
"
);
for
(
i
=
0
;
i
<
attached_thread_count
;
i
++
)
{
ret
=
GetExitCodeThread
(
attached_thread
[
i
],
&
code
);
...
...
@@ -1206,7 +1267,17 @@ static void child_process(const char *dll_name, DWORD target_offset)
ok
(
code
==
STILL_ACTIVE
,
"expected thread exit code STILL_ACTIVE, got %u
\n
"
,
code
);
}
Sleep
(
100
);
ret
=
WaitForSingleObject
(
attached_thread
[
0
],
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
attached_thread
[
1
],
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
event
,
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
mutex
,
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
semaphore
,
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
pRtlDllShutdownInProgress
();
ok
(
!
ret
,
"RtlDllShutdownInProgress returned %d
\n
"
,
ret
);
...
...
@@ -1224,6 +1295,7 @@ static void child_process(const char *dll_name, DWORD target_offset)
ret
=
pRtlDllShutdownInProgress
();
ok
(
!
ret
,
"RtlDllShutdownInProgress returned %d
\n
"
,
ret
);
trace
(
"call NtTerminateProcess(0, 195)
\n
"
);
status
=
pNtTerminateProcess
(
0
,
195
);
ok
(
!
status
,
"NtTerminateProcess error %#x
\n
"
,
status
);
...
...
@@ -1237,6 +1309,7 @@ static void child_process(const char *dll_name, DWORD target_offset)
ret
=
pRtlDllShutdownInProgress
();
ok
(
!
ret
,
"RtlDllShutdownInProgress returned %d
\n
"
,
ret
);
trace
(
"call FreeLibrary(%p)
\n
"
,
hmod
);
FreeLibrary
(
hmod
);
ret
=
pRtlDllShutdownInProgress
();
...
...
@@ -1254,6 +1327,7 @@ static void child_process(const char *dll_name, DWORD target_offset)
ret
=
pRtlDllShutdownInProgress
();
ok
(
!
ret
,
"RtlDllShutdownInProgress returned %d
\n
"
,
ret
);
trace
(
"call LdrShutdownProcess()
\n
"
);
pLdrShutdownProcess
();
ret
=
pRtlDllShutdownInProgress
();
...
...
@@ -1272,6 +1346,21 @@ static void child_process(const char *dll_name, DWORD target_offset)
else
if
(
test_dll_phase
==
3
)
expected_code
=
196
;
else
expected_code
=
STILL_ACTIVE
;
if
(
expected_code
==
STILL_ACTIVE
)
{
ret
=
WaitForSingleObject
(
attached_thread
[
0
],
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
attached_thread
[
1
],
0
);
ok
(
ret
==
WAIT_TIMEOUT
,
"expected WAIT_TIMEOUT, got %#x
\n
"
,
ret
);
}
else
{
ret
=
WaitForSingleObject
(
attached_thread
[
0
],
50
);
ok
(
ret
==
WAIT_OBJECT_0
,
"expected WAIT_OBJECT_0, got %#x
\n
"
,
ret
);
ret
=
WaitForSingleObject
(
attached_thread
[
1
],
50
);
ok
(
ret
==
WAIT_OBJECT_0
,
"expected WAIT_OBJECT_0, got %#x
\n
"
,
ret
);
}
for
(
i
=
0
;
i
<
attached_thread_count
;
i
++
)
{
ret
=
GetExitCodeThread
(
attached_thread
[
i
],
&
code
);
...
...
@@ -1385,6 +1474,7 @@ static void test_ExitProcess(void)
winetest_get_mainargs
(
&
argv
);
/* phase 0 */
*
child_failures
=
-
1
;
sprintf
(
cmdline
,
"
\"
%s
\"
loader %s %u 0"
,
argv
[
0
],
dll_name
,
target_offset
);
ret
=
CreateProcess
(
argv
[
0
],
cmdline
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
);
...
...
@@ -1397,6 +1487,7 @@ static void test_ExitProcess(void)
CloseHandle
(
pi
.
hThread
);
CloseHandle
(
pi
.
hProcess
);
/* phase 1 */
*
child_failures
=
-
1
;
sprintf
(
cmdline
,
"
\"
%s
\"
loader %s %u 1"
,
argv
[
0
],
dll_name
,
target_offset
);
ret
=
CreateProcess
(
argv
[
0
],
cmdline
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
);
...
...
@@ -1409,6 +1500,7 @@ static void test_ExitProcess(void)
CloseHandle
(
pi
.
hThread
);
CloseHandle
(
pi
.
hProcess
);
/* phase 2 */
*
child_failures
=
-
1
;
sprintf
(
cmdline
,
"
\"
%s
\"
loader %s %u 2"
,
argv
[
0
],
dll_name
,
target_offset
);
ret
=
CreateProcess
(
argv
[
0
],
cmdline
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
);
...
...
@@ -1421,6 +1513,7 @@ static void test_ExitProcess(void)
CloseHandle
(
pi
.
hThread
);
CloseHandle
(
pi
.
hProcess
);
/* phase 3 */
*
child_failures
=
-
1
;
sprintf
(
cmdline
,
"
\"
%s
\"
loader %s %u 3"
,
argv
[
0
],
dll_name
,
target_offset
);
ret
=
CreateProcess
(
argv
[
0
],
cmdline
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
);
...
...
@@ -1433,6 +1526,7 @@ static void test_ExitProcess(void)
CloseHandle
(
pi
.
hThread
);
CloseHandle
(
pi
.
hProcess
);
/* phase 4 */
*
child_failures
=
-
1
;
sprintf
(
cmdline
,
"
\"
%s
\"
loader %s %u 4"
,
argv
[
0
],
dll_name
,
target_offset
);
ret
=
CreateProcess
(
argv
[
0
],
cmdline
,
NULL
,
NULL
,
FALSE
,
0
,
NULL
,
NULL
,
&
si
,
&
pi
);
...
...
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