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
e22af18e
Commit
e22af18e
authored
Jun 20, 2008
by
Dan Hipschman
Committed by
Alexandre Julliard
Jun 23, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32/tests: Add tests for TLS functions.
parent
1ad733e4
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
228 additions
and
0 deletions
+228
-0
thread.c
dlls/kernel32/tests/thread.c
+228
-0
No files found.
dlls/kernel32/tests/thread.c
View file @
e22af18e
...
...
@@ -21,6 +21,7 @@
/* Define _WIN32_WINNT to get SetThreadIdealProcessor on Windows */
#define _WIN32_WINNT 0x0500
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
...
...
@@ -99,6 +100,57 @@ In addition there are no checks that the inheritance works properly in
CreateThread
*/
/* Functions to ensure that from a group of threads, only one executes
certain chunks of code at a time, and we know which one is executing
it. It basically makes multithreaded execution linear, which defeats
the purpose of multiple threads, but makes testing easy. */
static
HANDLE
all_synced
;
static
LONG
num_syncing_threads
,
num_synced
;
static
void
init_thread_sync_helpers
(
LONG
num_threads
)
{
all_synced
=
CreateEvent
(
NULL
,
FALSE
,
FALSE
,
NULL
);
ok
(
all_synced
!=
NULL
,
"CreateEvent failed
\n
"
);
num_syncing_threads
=
num_threads
;
num_synced
=
0
;
}
static
BOOL
sync_threads_and_run_one
(
DWORD
sync_id
,
DWORD
my_id
)
{
LONG
num
=
InterlockedIncrement
(
&
num_synced
);
assert
(
0
<
num
&&
num
<=
num_syncing_threads
);
if
(
num
==
num_syncing_threads
)
/* FIXME: MSDN claims PulseEvent is unreliable. For a test this isn't
so important, but we could use condition variables with more effort.
The given approach is clearer, though. */
PulseEvent
(
all_synced
);
else
{
DWORD
ret
=
WaitForSingleObject
(
all_synced
,
60000
);
ok
(
ret
==
WAIT_OBJECT_0
,
"WaitForSingleObject failed
\n
"
);
}
return
sync_id
==
my_id
;
}
static
void
resync_after_run
(
void
)
{
LONG
num
=
InterlockedDecrement
(
&
num_synced
);
assert
(
0
<=
num
&&
num
<
num_syncing_threads
);
if
(
num
==
0
)
PulseEvent
(
all_synced
);
else
{
DWORD
ret
=
WaitForSingleObject
(
all_synced
,
60000
);
ok
(
ret
==
WAIT_OBJECT_0
,
"WaitForSingleObject failed
\n
"
);
}
}
static
void
cleanup_thread_sync_helpers
(
void
)
{
CloseHandle
(
all_synced
);
all_synced
=
NULL
;
}
DWORD
tlsIndex
;
typedef
struct
{
...
...
@@ -953,6 +1005,181 @@ static void test_RegisterWaitForSingleObject(void)
ok
(
ret
,
"UnregisterWait failed with error %d
\n
"
,
GetLastError
());
}
static
DWORD
TLS_main
;
static
DWORD
TLS_index0
,
TLS_index1
;
static
DWORD
WINAPI
TLS_InheritanceProc
(
LPVOID
p
)
{
/* We should NOT inherit the TLS values from our parent or from the
main thread. */
LPVOID
val
;
val
=
TlsGetValue
(
TLS_main
);
ok
(
val
==
NULL
,
"TLS inheritance failed
\n
"
);
val
=
TlsGetValue
(
TLS_index0
);
ok
(
val
==
NULL
,
"TLS inheritance failed
\n
"
);
val
=
TlsGetValue
(
TLS_index1
);
ok
(
val
==
NULL
,
"TLS inheritance failed
\n
"
);
return
0
;
}
/* Basic TLS usage test. Make sure we can create slots and the values we
store in them are separate among threads. Also test TLS value
inheritance with TLS_InheritanceProc. */
static
DWORD
WINAPI
TLS_ThreadProc
(
LPVOID
p
)
{
LONG
id
=
(
LONG
)
p
;
LPVOID
val
;
BOOL
ret
;
if
(
sync_threads_and_run_one
(
0
,
id
))
{
TLS_index0
=
TlsAlloc
();
ok
(
TLS_index0
!=
TLS_OUT_OF_INDEXES
,
"TlsAlloc failed
\n
"
);
}
resync_after_run
();
if
(
sync_threads_and_run_one
(
1
,
id
))
{
TLS_index1
=
TlsAlloc
();
ok
(
TLS_index1
!=
TLS_OUT_OF_INDEXES
,
"TlsAlloc failed
\n
"
);
/* Slot indices should be different even if created in different
threads. */
ok
(
TLS_index0
!=
TLS_index1
,
"TlsAlloc failed
\n
"
);
/* Both slots should be initialized to NULL */
val
=
TlsGetValue
(
TLS_index0
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
NULL
,
"TLS slot not initialized correctly
\n
"
);
val
=
TlsGetValue
(
TLS_index1
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
NULL
,
"TLS slot not initialized correctly
\n
"
);
}
resync_after_run
();
if
(
sync_threads_and_run_one
(
0
,
id
))
{
val
=
TlsGetValue
(
TLS_index0
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
NULL
,
"TLS slot not initialized correctly
\n
"
);
val
=
TlsGetValue
(
TLS_index1
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
NULL
,
"TLS slot not initialized correctly
\n
"
);
ret
=
TlsSetValue
(
TLS_index0
,
(
LPVOID
)
1
);
ok
(
ret
,
"TlsSetValue failed
\n
"
);
ret
=
TlsSetValue
(
TLS_index1
,
(
LPVOID
)
2
);
ok
(
ret
,
"TlsSetValue failed
\n
"
);
val
=
TlsGetValue
(
TLS_index0
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
(
LPVOID
)
1
,
"TLS slot not initialized correctly
\n
"
);
val
=
TlsGetValue
(
TLS_index1
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
(
LPVOID
)
2
,
"TLS slot not initialized correctly
\n
"
);
}
resync_after_run
();
if
(
sync_threads_and_run_one
(
1
,
id
))
{
val
=
TlsGetValue
(
TLS_index0
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
NULL
,
"TLS slot not initialized correctly
\n
"
);
val
=
TlsGetValue
(
TLS_index1
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
NULL
,
"TLS slot not initialized correctly
\n
"
);
ret
=
TlsSetValue
(
TLS_index0
,
(
LPVOID
)
3
);
ok
(
ret
,
"TlsSetValue failed
\n
"
);
ret
=
TlsSetValue
(
TLS_index1
,
(
LPVOID
)
4
);
ok
(
ret
,
"TlsSetValue failed
\n
"
);
val
=
TlsGetValue
(
TLS_index0
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
(
LPVOID
)
3
,
"TLS slot not initialized correctly
\n
"
);
val
=
TlsGetValue
(
TLS_index1
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
(
LPVOID
)
4
,
"TLS slot not initialized correctly
\n
"
);
}
resync_after_run
();
if
(
sync_threads_and_run_one
(
0
,
id
))
{
HANDLE
thread
;
DWORD
waitret
;
val
=
TlsGetValue
(
TLS_index0
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
(
LPVOID
)
1
,
"TLS slot not initialized correctly
\n
"
);
val
=
TlsGetValue
(
TLS_index1
);
ok
(
GetLastError
()
==
ERROR_SUCCESS
,
"TlsGetValue failed
\n
"
);
ok
(
val
==
(
LPVOID
)
2
,
"TLS slot not initialized correctly
\n
"
);
thread
=
CreateThread
(
NULL
,
0
,
TLS_InheritanceProc
,
0
,
0
,
NULL
);
ok
(
thread
!=
NULL
,
"CreateThread failed
\n
"
);
waitret
=
WaitForSingleObject
(
thread
,
60000
);
ok
(
waitret
==
WAIT_OBJECT_0
,
"WaitForSingleObject failed
\n
"
);
CloseHandle
(
thread
);
ret
=
TlsFree
(
TLS_index0
);
ok
(
ret
,
"TlsFree failed
\n
"
);
}
resync_after_run
();
if
(
sync_threads_and_run_one
(
1
,
id
))
{
ret
=
TlsFree
(
TLS_index1
);
ok
(
ret
,
"TlsFree failed
\n
"
);
}
resync_after_run
();
return
0
;
}
static
void
test_TLS
(
void
)
{
HANDLE
threads
[
2
];
LONG
i
;
DWORD
ret
;
BOOL
suc
;
init_thread_sync_helpers
(
2
);
/* Allocate a TLS slot in the main thread to test for inheritance. */
TLS_main
=
TlsAlloc
();
ok
(
TLS_main
!=
TLS_OUT_OF_INDEXES
,
"TlsAlloc failed
\n
"
);
suc
=
TlsSetValue
(
TLS_main
,
(
LPVOID
)
4114
);
ok
(
suc
,
"TlsSetValue failed
\n
"
);
for
(
i
=
0
;
i
<
2
;
++
i
)
{
threads
[
i
]
=
CreateThread
(
NULL
,
0
,
TLS_ThreadProc
,
(
LPVOID
)
i
,
0
,
NULL
);
ok
(
threads
[
i
]
!=
NULL
,
"CreateThread failed
\n
"
);
}
ret
=
WaitForMultipleObjects
(
2
,
threads
,
TRUE
,
60000
);
ok
(
ret
==
WAIT_OBJECT_0
,
"WaitForMultipleObjects failed
\n
"
);
for
(
i
=
0
;
i
<
2
;
++
i
)
CloseHandle
(
threads
[
i
]);
suc
=
TlsFree
(
TLS_main
);
ok
(
suc
,
"TlsFree failed
\n
"
);
cleanup_thread_sync_helpers
();
}
START_TEST
(
thread
)
{
HINSTANCE
lib
;
...
...
@@ -1012,4 +1239,5 @@ START_TEST(thread)
#endif
test_QueueUserWorkItem
();
test_RegisterWaitForSingleObject
();
test_TLS
();
}
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