ReactOS 0.4.16-dev-334-g4d9f67c
thread.c File Reference
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <ntstatus.h>
#include <windef.h>
#include <winbase.h>
#include <winnt.h>
#include <winerror.h>
#include <winnls.h>
#include <winternl.h>
#include "wine/test.h"
Include dependency graph for thread.c:

Go to the source code of this file.

Classes

struct  t1Struct
 
struct  thread_actctx_param
 

Macros

#define WINE_NO_INLINE_STRING
 
#define WIN32_NO_STATUS
 
#define THREAD_ALL_ACCESS_NT4   (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
 
#define NUM_THREADS   4
 
#define USE_EXTENDED_PRIORITIES   0
 
#define CHECK_STACK   0
 
#define ARCH   "none"
 
#define obey_ar(x)
 
#define X(f)   p##f = (void*)GetProcAddress(hKernel32, #f)
 
#define X(f)   p##f = (void*)GetProcAddress(ntdll, #f)
 

Functions

static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE
 
static HANDLE (WINAPI *pOpenThread)(DWORD
 
static DWORD (WINAPI *pSetThreadIdealProcessor)(HANDLE
 
static void (WINAPI *pReleaseActCtx)(HANDLE)
 
static PTP_POOL (WINAPI *pCreateThreadpool)(PVOID)
 
static PTP_WORK (WINAPI *pCreateThreadpoolWork)(PTP_WORK_CALLBACK
 
static NTSTATUS (WINAPI *pNtQueryInformationThread)(HANDLE
 
static HANDLE create_target_process (const char *arg)
 
static void init_thread_sync_helpers (void)
 
static BOOL sync_threads_and_run_one (DWORD sync_id, DWORD my_id)
 
static void resync_after_run (void)
 
static void cleanup_thread_sync_helpers (void)
 
static DWORD WINAPI threadFunc1 (LPVOID p)
 
static DWORD WINAPI threadFunc2 (LPVOID p)
 
static DWORD WINAPI threadFunc3 (LPVOID p)
 
static DWORD WINAPI threadFunc4 (LPVOID p)
 
static DWORD WINAPI threadFunc_SetEvent (LPVOID p)
 
static DWORD WINAPI threadFunc_CloseHandle (LPVOID p)
 
static DWORD WINAPI thread_actctx_func (void *p)
 
static void create_function_addr_events (HANDLE events[2])
 
static VOID test_CreateRemoteThread (void)
 
static VOID test_CreateThread_basic (void)
 
static VOID test_CreateThread_suspended (void)
 
static VOID test_SuspendThread (void)
 
static VOID test_TerminateThread (void)
 
static VOID test_CreateThread_stack (void)
 
static VOID test_thread_priority (void)
 
static VOID test_GetThreadTimes (void)
 
static VOID test_thread_processor (void)
 
static VOID test_GetThreadExitCode (void)
 
static DWORD CALLBACK work_function (void *p)
 
static void test_QueueUserWorkItem (void)
 
static void CALLBACK signaled_function (PVOID p, BOOLEAN TimerOrWaitFired)
 
static void CALLBACK timeout_function (PVOID p, BOOLEAN TimerOrWaitFired)
 
static void test_RegisterWaitForSingleObject (void)
 
static PVOID (WINAPI *LS_GetValueFunc)(DWORD)
 
static DWORD WINAPI FLS_AllocFuncThunk (void)
 
static DWORD WINAPI LS_InheritanceProc (LPVOID p)
 
static DWORD WINAPI LS_ThreadProc (LPVOID p)
 
static void run_LS_tests (void)
 
static void test_TLS (void)
 
static void test_FLS (void)
 
static void test_ThreadErrorMode (void)
 
static void create_manifest_file (const char *filename, const char *manifest)
 
static HANDLE test_create (const char *file)
 
static void test_thread_actctx (void)
 
static void WINAPI threadpool_workcallback (PTP_CALLBACK_INSTANCE instance, void *context, PTP_WORK work)
 
static void test_threadpool (void)
 
static void test_reserved_tls (void)
 
static void test_thread_info (void)
 
static void init_funcs (void)
 
 START_TEST (thread)
 

Variables

static PBOOL
 
static BOOL
 
static DWORD
 
static PVOID
 
static ULONG
 
static HANDLE
 
static WAITORTIMERCALLBACK
 
static PDWORD
 
static ULONG_PTR
 
static PTP_CALLBACK_ENVIRON
 
static THREADINFOCLASS
 
static PULONG
 
static GROUP_AFFINITY *static const GROUP_AFFINITY GROUP_AFFINITY *static LPCVOID
 
static HANDLE start_event
 
static HANDLE stop_event
 
static LONG num_synced
 
static DWORD tlsIndex
 
static INT obeying_ars = 0
 
static HANDLE finish_event
 
static LONG times_executed
 
static DWORD LS_main
 
static DWORD LS_index0
 
static DWORD LS_index1
 
static DWORD LS_OutOfIndexesValue
 
static const charLS_AllocFuncName = ""
 
static const charLS_GetValueFuncName = ""
 
static const charLS_SetValueFuncName = ""
 
static const charLS_FreeFuncName = ""
 
static const char manifest_dep []
 
static const char manifest_main []
 

Macro Definition Documentation

◆ ARCH

#define ARCH   "none"

Definition at line 73 of file thread.c.

◆ CHECK_STACK

#define CHECK_STACK   0

Definition at line 46 of file thread.c.

◆ NUM_THREADS

#define NUM_THREADS   4

Definition at line 42 of file thread.c.

◆ obey_ar

#define obey_ar (   x)
Value:
(obeying_ars == 0 \
? ((x) \
? (obeying_ars = +1) \
: ((obeying_ars = -1), \
trace("not restricted, assuming consistent behaviour\n"))) \
: (obeying_ars < 0) \
? ok(!(x), "access restrictions obeyed\n") \
: ok( (x), "access restrictions not obeyed\n"))
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static INT obeying_ars
Definition: thread.c:197

Definition at line 198 of file thread.c.

◆ THREAD_ALL_ACCESS_NT4

#define THREAD_ALL_ACCESS_NT4   (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)

Definition at line 39 of file thread.c.

◆ USE_EXTENDED_PRIORITIES

#define USE_EXTENDED_PRIORITIES   0

Definition at line 44 of file thread.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 29 of file thread.c.

◆ WINE_NO_INLINE_STRING

#define WINE_NO_INLINE_STRING

Definition at line 26 of file thread.c.

◆ X [1/2]

#define X (   f)    p##f = (void*)GetProcAddress(hKernel32, #f)

◆ X [2/2]

#define X (   f)    p##f = (void*)GetProcAddress(ntdll, #f)

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pGetThreadPriorityBoost)
static

◆ cleanup_thread_sync_helpers()

static void cleanup_thread_sync_helpers ( void  )
static

Definition at line 180 of file thread.c.

181{
184}
#define CloseHandle
Definition: compat.h:739
static HANDLE stop_event
Definition: thread.c:135
static HANDLE start_event
Definition: thread.c:135

Referenced by run_LS_tests().

◆ create_function_addr_events()

static void create_function_addr_events ( HANDLE  events[2])
static

Definition at line 316 of file thread.c.

317{
318 char buffer[256];
319
320 sprintf(buffer, "threadFunc_SetEvent %p", threadFunc_SetEvent);
322
323 sprintf(buffer, "threadFunc_CloseHandle %p", threadFunc_CloseHandle);
325}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
GLuint buffer
Definition: glext.h:5915
#define sprintf(buf, format,...)
Definition: sprintf.c:55
HANDLE events[2]
Definition: event.c:4
static DWORD WINAPI threadFunc_SetEvent(LPVOID p)
Definition: thread.c:283
static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
Definition: thread.c:289
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637

Referenced by START_TEST(), and test_CreateRemoteThread().

◆ create_manifest_file()

static void create_manifest_file ( const char filename,
const char manifest 
)
static

Definition at line 1772 of file thread.c.

1773{
1775 HANDLE file;
1776 DWORD size;
1777
1780 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1783}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CP_ACP
Definition: compat.h:109
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define MultiByteToWideChar
Definition: compat.h:110
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
const char * filename
Definition: ioapi.h:137
#define CREATE_ALWAYS
Definition: disk.h:72
#define GENERIC_WRITE
Definition: nt_native.h:90
Definition: fci.c:127
static const CHAR manifest[]
Definition: v6util.h:41
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by test_thread_actctx().

◆ create_target_process()

static HANDLE create_target_process ( const char arg)
static

Definition at line 104 of file thread.c.

105{
106 char **argv;
107 char cmdline[MAX_PATH];
109 BOOL ret;
110 STARTUPINFOA si = { 0 };
111 si.cb = sizeof(si);
112
114 sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
115 ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
116 ok(ret, "error: %u\n", GetLastError());
117 ret = CloseHandle(pi.hThread);
118 ok(ret, "error %u\n", GetLastError());
119 return pi.hProcess;
120}
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4747
unsigned int BOOL
Definition: ntddk_ex.h:94
static refpint_t pi[]
Definition: server.c:96
#define argv
Definition: mplay32.c:18
int winetest_get_mainargs(char ***pargv)
TCHAR * cmdline
Definition: stretchblt.cpp:32
DWORD cb
Definition: winbase.h:856
int ret

Referenced by test_CreateRemoteThread().

◆ DWORD()

static DWORD ( WINAPI pSetThreadIdealProcessor)
static

◆ FLS_AllocFuncThunk()

static DWORD WINAPI FLS_AllocFuncThunk ( void  )
static

Definition at line 1349 of file thread.c.

1350{
1351 return pFlsAlloc(NULL);
1352}

Referenced by test_FLS().

◆ HANDLE()

static HANDLE ( WINAPI pOpenThread)
static

◆ init_funcs()

static void init_funcs ( void  )
static

Definition at line 2063 of file thread.c.

2064{
2065 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
2066 HMODULE ntdll = GetModuleHandleA("ntdll.dll");
2067
2068/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
2069 so that the compile passes */
2070
2071#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
2073 X(OpenThread);
2080 X(SetThreadErrorMode);
2081 X(GetThreadErrorMode);
2087
2088 X(CreateThreadpool);
2089 X(CloseThreadpool);
2090 X(CreateThreadpoolWork);
2091 X(SubmitThreadpoolWork);
2092 X(WaitForThreadpoolWorkCallbacks);
2093 X(CloseThreadpoolWork);
2094
2095 X(GetThreadGroupAffinity);
2096 X(SetThreadGroupAffinity);
2097
2098 X(FlsAlloc);
2099 X(FlsFree);
2100 X(FlsSetValue);
2101 X(FlsGetValue);
2102#undef X
2103
2104#define X(f) p##f = (void*)GetProcAddress(ntdll, #f)
2105 if (ntdll)
2106 {
2111 }
2112#undef X
2113}
#define IsWow64Process
Definition: compat.h:760
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
BOOL WINAPI GetCurrentActCtx(OUT PHANDLE phActCtx)
Definition: actctx.c:298
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
Definition: fiber.c:460
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
Definition: fiber.c:481
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
Definition: fiber.c:400
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
Definition: fiber.c:341
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HANDLE WINAPI OpenThread(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwThreadId)
Definition: thread.c:403
BOOL WINAPI QueueUserWorkItem(IN LPTHREAD_START_ROUTINE Function, IN PVOID Context, IN ULONG Flags)
Definition: thread.c:1076
DWORD WINAPI SetThreadIdealProcessor(IN HANDLE hThread, IN DWORD dwIdealProcessor)
Definition: thread.c:866
BOOL WINAPI GetThreadPriorityBoost(IN HANDLE hThread, OUT PBOOL pDisablePriorityBoost)
Definition: thread.c:778
BOOL NTAPI SetThreadPriorityBoost(IN HANDLE hThread, IN BOOL bDisablePriorityBoost)
Definition: thread.c:804
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:102
NTSYSAPI DWORD WINAPI RtlGetThreadErrorMode(void)
Definition: error.c:217
HANDLE hKernel32
Definition: locale.c:13
#define X(f)
NTSTATUS NTAPI NtSetLdtEntries(ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2)
Definition: stubs.c:185
NTSTATUS NTAPI NtQueryInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:2624
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREADINFOCLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength)
Definition: query.c:2018
BOOL WINAPI RegisterWaitForSingleObject(OUT PHANDLE phNewWaitObject, IN HANDLE hObject, IN WAITORTIMERCALLBACK Callback, IN PVOID Context, IN ULONG dwMilliseconds, IN ULONG dwFlags)
Definition: synch.c:850
BOOL WINAPI UnregisterWait(IN HANDLE WaitHandle)
Definition: synch.c:934

Referenced by START_TEST().

◆ init_thread_sync_helpers()

static void init_thread_sync_helpers ( void  )
static

Definition at line 138 of file thread.c.

139{
141 ok(start_event != NULL, "CreateEvent failed\n");
143 ok(stop_event != NULL, "CreateEvent failed\n");
144 num_synced = -1;
145}
#define TRUE
Definition: types.h:120
static LONG num_synced
Definition: thread.c:136
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651

Referenced by run_LS_tests().

◆ LS_InheritanceProc()

static DWORD WINAPI LS_InheritanceProc ( LPVOID  p)
static

Definition at line 1354 of file thread.c.

1355{
1356 /* We should NOT inherit the FLS/TLS values from our parent or from the
1357 main thread. */
1358 LPVOID val;
1359
1360 val = LS_GetValueFunc(LS_main);
1361 ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1362
1363 val = LS_GetValueFunc(LS_index0);
1364 ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1365
1366 val = LS_GetValueFunc(LS_index1);
1367 ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1368
1369 return 0;
1370}
GLuint GLfloat * val
Definition: glext.h:7180
static DWORD LS_index1
Definition: thread.c:1327
static DWORD LS_main
Definition: thread.c:1326
static DWORD LS_index0
Definition: thread.c:1327
static const char * LS_GetValueFuncName
Definition: thread.c:1338

Referenced by LS_ThreadProc().

◆ LS_ThreadProc()

static DWORD WINAPI LS_ThreadProc ( LPVOID  p)
static

Definition at line 1375 of file thread.c.

1376{
1377 LONG_PTR id = (LONG_PTR) p;
1378 LPVOID val;
1379 BOOL ret;
1380
1381 if (sync_threads_and_run_one(0, id))
1382 {
1383 LS_index0 = LS_AllocFunc();
1385 }
1387
1388 if (sync_threads_and_run_one(1, id))
1389 {
1390 LS_index1 = LS_AllocFunc();
1392
1393 /* Slot indices should be different even if created in different
1394 threads. */
1395 ok(LS_index0 != LS_index1, "%s failed\n", LS_AllocFuncName);
1396
1397 /* Both slots should be initialized to NULL */
1398 SetLastError(0xdeadbeef);
1399 val = LS_GetValueFunc(LS_index0);
1400 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1401 ok(val == NULL, "Slot not initialized correctly\n");
1402
1403 SetLastError(0xdeadbeef);
1404 val = LS_GetValueFunc(LS_index1);
1405 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1406 ok(val == NULL, "Slot not initialized correctly\n");
1407 }
1409
1410 if (sync_threads_and_run_one(0, id))
1411 {
1412 SetLastError(0xdeadbeef);
1413 val = LS_GetValueFunc(LS_index0);
1414 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1415 ok(val == NULL, "Slot not initialized correctly\n");
1416
1417 SetLastError(0xdeadbeef);
1418 val = LS_GetValueFunc(LS_index1);
1419 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1420 ok(val == NULL, "Slot not initialized correctly\n");
1421
1422 ret = LS_SetValueFunc(LS_index0, (LPVOID) 1);
1423 ok(ret, "%s failed\n", LS_SetValueFuncName);
1424
1425 ret = LS_SetValueFunc(LS_index1, (LPVOID) 2);
1426 ok(ret, "%s failed\n", LS_SetValueFuncName);
1427
1428 SetLastError(0xdeadbeef);
1429 val = LS_GetValueFunc(LS_index0);
1430 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1431 ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
1432
1433 SetLastError(0xdeadbeef);
1434 val = LS_GetValueFunc(LS_index1);
1435 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1436 ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
1437 }
1439
1440 if (sync_threads_and_run_one(1, id))
1441 {
1442 val = LS_GetValueFunc(LS_index0);
1443 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1444 ok(val == NULL, "Slot not initialized correctly\n");
1445
1446 val = LS_GetValueFunc(LS_index1);
1447 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1448 ok(val == NULL, "Slot not initialized correctly\n");
1449
1450 ret = LS_SetValueFunc(LS_index0, (LPVOID) 3);
1451 ok(ret, "%s failed\n", LS_SetValueFuncName);
1452
1453 ret = LS_SetValueFunc(LS_index1, (LPVOID) 4);
1454 ok(ret, "%s failed\n", LS_SetValueFuncName);
1455
1456 val = LS_GetValueFunc(LS_index0);
1457 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1458 ok(val == (LPVOID) 3, "Slot not initialized correctly\n");
1459
1460 val = LS_GetValueFunc(LS_index1);
1461 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1462 ok(val == (LPVOID) 4, "Slot not initialized correctly\n");
1463 }
1465
1466 if (sync_threads_and_run_one(0, id))
1467 {
1468 HANDLE thread;
1469 DWORD waitret, tid;
1470
1471 val = LS_GetValueFunc(LS_index0);
1472 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1473 ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
1474
1475 val = LS_GetValueFunc(LS_index1);
1476 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1477 ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
1478
1480 ok(thread != NULL, "CreateThread failed\n");
1481 waitret = WaitForSingleObject(thread, 60000);
1482 ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1484
1485 ret = LS_FreeFunc(LS_index0);
1486 ok(ret, "%s failed\n", LS_FreeFuncName);
1487 }
1489
1490 if (sync_threads_and_run_one(1, id))
1491 {
1492 ret = LS_FreeFunc(LS_index1);
1493 ok(ret, "%s failed\n", LS_FreeFuncName);
1494 }
1496
1497 return 0;
1498}
static HANDLE thread
Definition: service.c:33
#define ERROR_SUCCESS
Definition: deptool.c:10
#define SetLastError(x)
Definition: compat.h:752
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
GLfloat GLfloat p
Definition: glext.h:8902
static const char * LS_SetValueFuncName
Definition: thread.c:1339
static const char * LS_AllocFuncName
Definition: thread.c:1337
static const char * LS_FreeFuncName
Definition: thread.c:1340
static DWORD WINAPI LS_InheritanceProc(LPVOID p)
Definition: thread.c:1354
static void resync_after_run(void)
Definition: thread.c:164
static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
Definition: thread.c:147
static DWORD LS_OutOfIndexesValue
Definition: thread.c:1328
static TfClientId tid
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define LONG_PTR
Definition: treelist.c:79
#define WAIT_OBJECT_0
Definition: winbase.h:432

Referenced by run_LS_tests().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pNtQueryInformationThread)
static

◆ PTP_POOL()

static PTP_POOL ( WINAPI pCreateThreadpool)
static

◆ PTP_WORK()

static PTP_WORK ( WINAPI pCreateThreadpoolWork)
static

◆ PVOID()

static PVOID ( WINAPI LS_GetValueFunc)
static

◆ resync_after_run()

static void resync_after_run ( void  )
static

Definition at line 164 of file thread.c.

165{
167 assert(-1 <= num && num <= 1);
168 if (num == -1)
169 {
172 }
173 else
174 {
176 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
177 }
178}
#define InterlockedDecrement
Definition: armddk.h:52
#define assert(x)
Definition: debug.h:53
GLuint GLuint num
Definition: glext.h:9618
long LONG
Definition: pedump.c:60
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714

Referenced by LS_ThreadProc().

◆ run_LS_tests()

static void run_LS_tests ( void  )
static

Definition at line 1500 of file thread.c.

1501{
1502 HANDLE threads[2];
1503 LONG_PTR i;
1504 DWORD ret;
1505 BOOL suc;
1506
1508
1509 /* Allocate a slot in the main thread to test for inheritance. */
1510 LS_main = LS_AllocFunc();
1511 ok(LS_main != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
1512 suc = LS_SetValueFunc(LS_main, (LPVOID) 4114);
1513 ok(suc, "%s failed\n", LS_SetValueFuncName);
1514
1515 for (i = 0; i < 2; ++i)
1516 {
1517 DWORD tid;
1518
1520 ok(threads[i] != NULL, "CreateThread failed\n");
1521 }
1522
1523 ret = WaitForMultipleObjects(2, threads, TRUE, 60000);
1524 ok(ret == WAIT_OBJECT_0 || broken(ret == WAIT_OBJECT_0+1 /* nt4,w2k */), "WaitForAllObjects 2 threads %d\n",ret);
1525
1526 for (i = 0; i < 2; ++i)
1528
1529 suc = LS_FreeFunc(LS_main);
1530 ok(suc, "%s failed\n", LS_FreeFuncName);
1532}
#define broken(x)
Definition: atltest.h:178
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static HANDLE ULONG_PTR DWORD threads
Definition: process.c:81
static void cleanup_thread_sync_helpers(void)
Definition: thread.c:180
static DWORD WINAPI LS_ThreadProc(LPVOID p)
Definition: thread.c:1375
static void init_thread_sync_helpers(void)
Definition: thread.c:138
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151

Referenced by test_FLS(), and test_TLS().

◆ signaled_function()

static void CALLBACK signaled_function ( PVOID  p,
BOOLEAN  TimerOrWaitFired 
)
static

Definition at line 1255 of file thread.c.

1256{
1257 HANDLE event = p;
1258 SetEvent(event);
1259 ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
1260}
struct _cl_event * event
Definition: glext.h:7739

Referenced by test_RegisterWaitForSingleObject().

◆ START_TEST()

START_TEST ( thread  )

Definition at line 2115 of file thread.c.

2116{
2117 int argc;
2118 char **argv;
2120
2121 init_funcs();
2122
2123 if (argc >= 3)
2124 {
2125 if (!strcmp(argv[2], "sleep"))
2126 {
2127 HANDLE hAddrEvents[2];
2128 create_function_addr_events(hAddrEvents);
2129 SetEvent(hAddrEvents[0]);
2130 SetEvent(hAddrEvents[1]);
2131 Sleep(5000); /* spawned process runs for at most 5 seconds */
2132 return;
2133 }
2134 while (1)
2135 {
2137 DWORD tid;
2139 ok(hThread != NULL, "CreateThread failed, error %u\n",
2140 GetLastError());
2142 "Thread did not exit in time\n");
2143 if (hThread == NULL) break;
2145 }
2146 return;
2147 }
2148
2161#ifdef __i386__
2162 test_SetThreadContext();
2163 test_GetThreadSelectorEntry();
2164 test_NtSetLdtEntries();
2165#endif
2168 test_TLS();
2169 test_FLS();
2171#if (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || (defined(_MSC_VER) && defined(__i386__))
2172 test_thread_fpu_cw();
2173#endif
2175
2177}
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static VOID test_GetThreadTimes(void)
Definition: thread.c:793
static void test_thread_actctx(void)
Definition: thread.c:1812
static VOID test_CreateThread_stack(void)
Definition: thread.c:646
static void test_threadpool(void)
Definition: thread.c:1898
static VOID test_SuspendThread(void)
Definition: thread.c:554
static void create_function_addr_events(HANDLE events[2])
Definition: thread.c:316
static VOID test_CreateThread_basic(void)
Definition: thread.c:418
static VOID test_CreateThread_suspended(void)
Definition: thread.c:515
static void test_RegisterWaitForSingleObject(void)
Definition: thread.c:1269
static VOID test_thread_processor(void)
Definition: thread.c:850
static VOID test_thread_priority(void)
Definition: thread.c:673
static VOID test_CreateRemoteThread(void)
Definition: thread.c:328
static void test_reserved_tls(void)
Definition: thread.c:1922
static DWORD WINAPI threadFunc2(LPVOID p)
Definition: thread.c:240
static void test_FLS(void)
Definition: thread.c:1551
static VOID test_TerminateThread(void)
Definition: thread.c:609
static void init_funcs(void)
Definition: thread.c:2063
static void test_QueueUserWorkItem(void)
Definition: thread.c:1227
static void test_TLS(void)
Definition: thread.c:1534
static void test_thread_info(void)
Definition: thread.c:1959
static void test_ThreadErrorMode(void)
Definition: thread.c:1574
static VOID test_GetThreadExitCode(void)
Definition: thread.c:993
HANDLE hThread
Definition: wizard.c:28
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790

◆ sync_threads_and_run_one()

static BOOL sync_threads_and_run_one ( DWORD  sync_id,
DWORD  my_id 
)
static

Definition at line 147 of file thread.c.

148{
150 assert(-1 <= num && num <= 1);
151 if (num == 1)
152 {
155 }
156 else
157 {
159 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed %x\n",ret);
160 }
161 return sync_id == my_id;
162}
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by LS_ThreadProc().

◆ test_create()

static HANDLE test_create ( const char file)
static

Definition at line 1785 of file thread.c.

1786{
1788 ACTCTXW actctx;
1789 HANDLE handle;
1790
1792 memset(&actctx, 0, sizeof(ACTCTXW));
1793 actctx.cbSize = sizeof(ACTCTXW);
1794 actctx.lpSource = path;
1795
1796 handle = pCreateActCtxW(&actctx);
1797 ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
1798
1799 ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
1800 ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
1801 ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
1802 ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
1803 ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
1804 ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
1805 ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
1806 ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
1807 ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
1808
1809 return handle;
1810}
#define actctx
Definition: kernel32.h:8
#define memset(x, y, z)
Definition: compat.h:39

◆ test_CreateRemoteThread()

static VOID test_CreateRemoteThread ( void  )
static

Definition at line 328 of file thread.c.

329{
330 HANDLE hProcess, hThread, hEvent, hRemoteEvent;
331 DWORD tid, ret, exitcode;
332 HANDLE hAddrEvents[2];
333
335 ok(hProcess != NULL, "Can't start process\n");
336
337 /* ensure threadFunc_SetEvent & threadFunc_CloseHandle are the same
338 * address as in the child process */
339 create_function_addr_events(hAddrEvents);
340 ret = WaitForMultipleObjects(2, hAddrEvents, TRUE, 5000);
341 if (ret == WAIT_TIMEOUT)
342 {
343 skip("child process wasn't mapped at same address, so can't do CreateRemoteThread tests.\n");
344 return;
345 }
346 ok(ret == WAIT_OBJECT_0 || broken(ret == WAIT_OBJECT_0+1 /* nt4,w2k */), "WaitForAllObjects 2 events %d\n", ret);
347
349 ok(hEvent != NULL, "Can't create event, err=%u\n", GetLastError());
352 ok(ret != 0, "DuplicateHandle failed, err=%u\n", GetLastError());
353
354 /* create suspended remote thread with entry point SetEvent() */
355 SetLastError(0xdeadbeef);
357 hRemoteEvent, CREATE_SUSPENDED, &tid);
359 {
360 win_skip("CreateRemoteThread is not implemented\n");
361 goto cleanup;
362 }
363 ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
364 ok(tid != 0, "null tid\n");
366 ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
368 ok(ret == 2, "ret=%u, err=%u\n", ret, GetLastError());
369
370 /* thread still suspended, so wait times out */
372 ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
373
375 ok(ret == 1, "ret=%u, err=%u\n", ret, GetLastError());
376
377 /* wait that doesn't time out */
379 ok(ret == WAIT_OBJECT_0, "object not signaled, ret=%u\n", ret);
380
381 /* wait for thread end */
383 ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
385
386 /* create and wait for remote thread with entry point CloseHandle() */
389 hRemoteEvent, 0, &tid);
390 ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
392 ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%u\n", ret);
394
395 /* create remote thread with entry point SetEvent() */
398 hRemoteEvent, 0, &tid);
399 ok(hThread != NULL, "CreateRemoteThread failed, err=%u\n", GetLastError());
400
401 /* closed handle, so wait times out */
403 ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%u\n", ret);
404
405 /* check that remote SetEvent() failed */
406 ret = GetExitCodeThread(hThread, &exitcode);
407 ok(ret != 0, "GetExitCodeThread failed, err=%u\n", GetLastError());
408 if (ret) ok(exitcode == 0, "SetEvent succeeded, expected to fail\n");
410
411cleanup:
415}
#define skip(...)
Definition: atltest.h:64
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define GetCurrentProcess()
Definition: compat.h:759
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
HANDLE WINAPI CreateRemoteThread(IN HANDLE hProcess, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:159
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:642
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
static HANDLE hEvent
Definition: comm.c:54
static HANDLE create_target_process(const char *arg)
Definition: thread.c:104
#define win_skip
Definition: test.h:163
#define CREATE_SUSPENDED
Definition: winbase.h:181
#define DUPLICATE_SAME_ACCESS

Referenced by START_TEST().

◆ test_CreateThread_basic()

static VOID test_CreateThread_basic ( void  )
static

Definition at line 418 of file thread.c.

419{
421 DWORD threadid[NUM_THREADS],curthreadId;
422 DWORD threadmem[NUM_THREADS];
423 DWORD exitCode;
424 t1Struct tstruct[NUM_THREADS];
425 int error;
426 DWORD i,j;
427 DWORD GLE, ret;
428 DWORD tid;
429 BOOL bRet;
430
431 /* lstrlenA contains an exception handler so this makes sure exceptions work in the main thread */
432 ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
433
434/* Retrieve current Thread ID for later comparisons */
435 curthreadId=GetCurrentThreadId();
436/* Allocate some local storage */
437 ok((tlsIndex=TlsAlloc())!=TLS_OUT_OF_INDEXES,"TlsAlloc failed\n");
438/* Create events for thread synchronization */
439 for(i=0;i<NUM_THREADS;i++) {
440 threadmem[i]=0;
441/* Note that it doesn't matter what type of event we choose here. This
442 test isn't trying to thoroughly test events
443*/
445 tstruct[i].threadnum=i;
446 tstruct[i].threadmem=threadmem;
447 tstruct[i].event=event;
448 }
449
450/* Test that passing arguments to threads works okay */
451 for(i=0;i<NUM_THREADS;i++) {
453 &tstruct[i],0,&threadid[i]);
454 ok(thread[i]!=NULL,"Create Thread failed\n");
455 }
456/* Test that the threads actually complete */
457 for(i=0;i<NUM_THREADS;i++) {
459 ok(error==WAIT_OBJECT_0, "Thread did not complete within timelimit\n");
460 if(error!=WAIT_OBJECT_0) {
462 }
463 ok(GetExitCodeThread(thread[i],&exitCode),"Could not retrieve ext code\n");
464 ok(exitCode==i+NUM_THREADS,"Thread returned an incorrect exit code\n");
465 }
466/* Test that each thread executed in its parent's address space
467 (it was able to change threadmem and pass that change back to its parent)
468 and that each thread id was independent). Note that we prove that the
469 threads actually execute concurrently by having them block on each other
470 in threadFunc1
471*/
472 for(i=0;i<NUM_THREADS;i++) {
473 error=0;
474 for(j=i+1;j<NUM_THREADS;j++) {
475 if (threadmem[i]==threadmem[j]) {
476 error=1;
477 }
478 }
479 ok(!error && threadmem[i]==threadid[i] && threadmem[i]!=curthreadId,
480 "Thread did not execute successfully\n");
481 ok(CloseHandle(thread[i])!=0,"CloseHandle failed\n");
482 }
483
484 SetLastError(0xCAFEF00D);
485 bRet = TlsFree(tlsIndex);
486 ok(bRet, "TlsFree failed: %08x\n", GetLastError());
487 ok(GetLastError()==0xCAFEF00D,
488 "GetLastError: expected 0xCAFEF00D, got %08x\n", GetLastError());
489
490 /* Test freeing an already freed TLS index */
491 SetLastError(0xCAFEF00D);
492 ok(TlsFree(tlsIndex)==0,"TlsFree succeeded\n");
494 "GetLastError: expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
495
496 /* Test how passing NULL as a pointer to threadid works */
497 SetLastError(0xFACEaBAD);
499 GLE = GetLastError();
500 if (thread[0]) { /* NT */
501 ok(GLE==0xFACEaBAD, "CreateThread set last error to %d, expected 4207848365\n", GLE);
503 ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
504 ret = GetExitCodeThread(thread[0],&exitCode);
505 ok(ret!=0, "GetExitCodeThread returned %d (expected nonzero)\n", ret);
506 ok(exitCode==99, "threadFunc2 exited with code: %d (expected 99)\n", exitCode);
507 ok(CloseHandle(thread[0])!=0,"Error closing thread handle\n");
508 }
509 else { /* 9x */
510 ok(GLE==ERROR_INVALID_PARAMETER, "CreateThread set last error to %d, expected 87\n", GLE);
511 }
512}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
DWORD WINAPI TlsAlloc(VOID)
Definition: thread.c:1100
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:587
BOOL WINAPI TlsFree(IN DWORD Index)
Definition: thread.c:1166
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define error(str)
Definition: mkdosfs.c:1605
static DWORD GLE
Definition: registry.c:38
static DWORD WINAPI threadFunc1(LPVOID p)
Definition: thread.c:212
#define NUM_THREADS
Definition: thread.c:42
static DWORD tlsIndex
Definition: thread.c:186
int threadnum
Definition: thread.c:189
DWORD * threadmem
Definition: thread.c:191
HANDLE * event
Definition: thread.c:190
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define TLS_OUT_OF_INDEXES
Definition: winbase.h:575

Referenced by START_TEST().

◆ test_CreateThread_stack()

static VOID test_CreateThread_stack ( void  )
static

Definition at line 646 of file thread.c.

647{
648#if CHECK_STACK
649/* The only way I know of to test the stack size is to use alloca
650 and __try/__except. However, this is probably not portable,
651 and I couldn't get it to work under Wine anyhow. However, here
652 is the code which should allow for testing that CreateThread
653 respects the stack-size limit
654*/
656 DWORD threadId,exitCode;
657
658 SYSTEM_INFO sysInfo;
659 sysInfo.dwPageSize=0;
660 GetSystemInfo(&sysInfo);
661 ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
663 threadFunc5,&exitCode,
664 0,&threadId);
666 "TerminateThread didn't work\n");
667 ok(exitCode==1,"CreateThread did not obey stack-size-limit\n");
668 ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
669#endif
670}
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
DWORD dwPageSize
Definition: winbase.h:1198

Referenced by START_TEST().

◆ test_CreateThread_suspended()

static VOID test_CreateThread_suspended ( void  )
static

Definition at line 515 of file thread.c.

516{
518 DWORD threadId;
519 DWORD suspend_count;
520 int error;
521
523 CREATE_SUSPENDED,&threadId);
524 ok(thread!=NULL,"Create Thread failed\n");
525/* Check that the thread is suspended */
526 ok(SuspendThread(thread)==1,"Thread did not start suspended\n");
527 ok(ResumeThread(thread)==2,"Resume thread returned an invalid value\n");
528/* Check that resume thread didn't actually start the thread. I can't think
529 of a better way of checking this than just waiting. I am not sure if this
530 will work on slow computers.
531*/
533 "ResumeThread should not have actually started the thread\n");
534/* Now actually resume the thread and make sure that it actually completes*/
535 ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
537 "Thread did not resume\n");
538 if(error!=WAIT_OBJECT_0) {
540 }
541
542 suspend_count = SuspendThread(thread);
543 ok(suspend_count == -1, "SuspendThread returned %d, expected -1\n", suspend_count);
544
545 suspend_count = ResumeThread(thread);
546 ok(suspend_count == 0 ||
547 broken(suspend_count == -1), /* win9x */
548 "ResumeThread returned %d, expected 0\n", suspend_count);
549
550 ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
551}

Referenced by START_TEST().

◆ test_FLS()

static void test_FLS ( void  )
static

Definition at line 1551 of file thread.c.

1552{
1553 if (!pFlsAlloc || !pFlsFree || !pFlsGetValue || !pFlsSetValue)
1554 {
1555 win_skip("Fiber Local Storage not supported\n");
1556 return;
1557 }
1558
1560
1561 LS_AllocFunc = &FLS_AllocFuncThunk;
1562 LS_GetValueFunc = pFlsGetValue;
1563 LS_SetValueFunc = pFlsSetValue;
1564 LS_FreeFunc = pFlsFree;
1565
1566 LS_AllocFuncName = "FlsAlloc";
1567 LS_GetValueFuncName = "FlsGetValue";
1568 LS_SetValueFuncName = "FlsSetValue";
1569 LS_FreeFuncName = "FlsFree";
1570
1571 run_LS_tests();
1572}
static void run_LS_tests(void)
Definition: thread.c:1500
static DWORD WINAPI FLS_AllocFuncThunk(void)
Definition: thread.c:1349
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:602

Referenced by START_TEST().

◆ test_GetThreadExitCode()

static VOID test_GetThreadExitCode ( void  )
static

Definition at line 993 of file thread.c.

994{
995 DWORD exitCode, threadid;
996 DWORD GLE, ret;
998
999 ret = GetExitCodeThread((HANDLE)0x2bad2bad,&exitCode);
1000 ok(ret==0, "GetExitCodeThread returned non zero value: %d\n", ret);
1001 GLE = GetLastError();
1002 ok(GLE==ERROR_INVALID_HANDLE, "GetLastError returned %d (expected 6)\n", GLE);
1003
1004 thread = CreateThread(NULL,0,threadFunc2,NULL,0,&threadid);
1006 ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
1007 ret = GetExitCodeThread(thread,&exitCode);
1008 ok(ret==exitCode || ret==1,
1009 "GetExitCodeThread returned %d (expected 1 or %d)\n", ret, exitCode);
1010 ok(exitCode==99, "threadFunc2 exited with code %d (expected 99)\n", exitCode);
1011 ok(CloseHandle(thread)!=0,"Error closing thread handle\n");
1012}
#define ERROR_INVALID_HANDLE
Definition: compat.h:98

Referenced by START_TEST().

◆ test_GetThreadTimes()

static VOID test_GetThreadTimes ( void  )
static

Definition at line 793 of file thread.c.

794{
795 HANDLE thread,access_thread=NULL;
796 FILETIME creationTime,exitTime,kernelTime,userTime;
797 DWORD threadId;
798 int error;
799
801 CREATE_SUSPENDED,&threadId);
802
803 ok(thread!=NULL,"Create Thread failed\n");
804/* check that access control is obeyed */
805 if (pOpenThread) {
806 access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 &
807 (~THREAD_QUERY_INFORMATION), 0,threadId);
808 ok(access_thread!=NULL,
809 "OpenThread returned an invalid handle\n");
810 }
811 ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
813 "ResumeThread didn't work\n");
814 creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
815 exitTime.dwLowDateTime=99; exitTime.dwHighDateTime=99;
816 kernelTime.dwLowDateTime=99; kernelTime.dwHighDateTime=99;
817 userTime.dwLowDateTime=99; userTime.dwHighDateTime=99;
818/* GetThreadTimes should set all of the parameters passed to it */
819 error=GetThreadTimes(thread,&creationTime,&exitTime,
820 &kernelTime,&userTime);
821
823 win_skip("GetThreadTimes is not implemented\n");
824 else {
825 ok(error!=0,"GetThreadTimes failed\n");
826 ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
827 "creationTime was invalid\n");
828 ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
829 "exitTime was invalid\n");
830 ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
831 "kernelTimewas invalid\n");
832 ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
833 "userTime was invalid\n");
834 ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
835 if(access_thread!=NULL)
836 {
837 error=GetThreadTimes(access_thread,&creationTime,&exitTime,
838 &kernelTime,&userTime);
839 obey_ar(error==0);
840 }
841 }
842 if(access_thread!=NULL) {
843 ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
844 }
845}
BOOL NTAPI GetThreadTimes(IN HANDLE hThread, OUT LPFILETIME lpCreationTime, OUT LPFILETIME lpExitTime, OUT LPFILETIME lpKernelTime, OUT LPFILETIME lpUserTime)
Definition: thread.c:469
#define THREAD_QUERY_INFORMATION
Definition: pstypes.h:150
#define THREAD_ALL_ACCESS_NT4
Definition: thread.c:39
#define obey_ar(x)
Definition: thread.c:198
DWORD dwHighDateTime
Definition: mapidefs.h:66
DWORD dwLowDateTime
Definition: mapidefs.h:65

Referenced by START_TEST().

◆ test_QueueUserWorkItem()

static void test_QueueUserWorkItem ( void  )
static

Definition at line 1227 of file thread.c.

1228{
1229 INT_PTR i;
1230 DWORD wait_result;
1232
1233 /* QueueUserWorkItem not present on win9x */
1234 if (!pQueueUserWorkItem) return;
1235
1237
1238 before = GetTickCount();
1239
1240 for (i = 0; i < 100; i++)
1241 {
1242 BOOL ret = pQueueUserWorkItem(work_function, (void *)i, WT_EXECUTEDEFAULT);
1243 ok(ret, "QueueUserWorkItem failed with error %d\n", GetLastError());
1244 }
1245
1246 wait_result = WaitForSingleObject(finish_event, 10000);
1247
1248 after = GetTickCount();
1249 trace("100 QueueUserWorkItem calls took %dms\n", after - before);
1250 ok(wait_result == WAIT_OBJECT_0, "wait failed with error 0x%x\n", wait_result);
1251
1252 ok(times_executed == 100, "didn't execute all of the work items\n");
1253}
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
static DWORD CALLBACK work_function(void *p)
Definition: thread.c:1218
static HANDLE finish_event
Definition: thread.c:1215
static LONG times_executed
Definition: thread.c:1216
__inline int before(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2390
__inline int after(__u32 seq1, __u32 seq2)
Definition: tcpcore.h:2395
int32_t INT_PTR
Definition: typedefs.h:64
#define WT_EXECUTEDEFAULT
Definition: winnt_old.h:1067

Referenced by START_TEST().

◆ test_RegisterWaitForSingleObject()

static void test_RegisterWaitForSingleObject ( void  )
static

Definition at line 1269 of file thread.c.

1270{
1271 BOOL ret;
1272 HANDLE wait_handle;
1273 HANDLE handle;
1275
1276 if (!pRegisterWaitForSingleObject || !pUnregisterWait)
1277 {
1278 win_skip("RegisterWaitForSingleObject or UnregisterWait not implemented\n");
1279 return;
1280 }
1281
1282 /* test signaled case */
1283
1286
1287 ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1288 ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1289
1291 /* give worker thread chance to complete */
1292 Sleep(100);
1293
1294 ret = pUnregisterWait(wait_handle);
1295 ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1296
1297 /* test cancel case */
1298
1300
1301 ret = pRegisterWaitForSingleObject(&wait_handle, handle, signaled_function, complete_event, INFINITE, WT_EXECUTEONLYONCE);
1302 ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1303
1304 ret = pUnregisterWait(wait_handle);
1305 ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1306
1307 /* test timeout case */
1308
1309 ret = pRegisterWaitForSingleObject(&wait_handle, handle, timeout_function, complete_event, 0, WT_EXECUTEONLYONCE);
1310 ok(ret, "RegisterWaitForSingleObject failed with error %d\n", GetLastError());
1311
1313 /* give worker thread chance to complete */
1314 Sleep(100);
1315
1316 ret = pUnregisterWait(wait_handle);
1317 ok(ret, "UnregisterWait failed with error %d\n", GetLastError());
1318
1319 SetLastError(0xdeadbeef);
1320 ret = pUnregisterWait(NULL);
1321 ok(!ret, "Expected UnregisterWait to fail\n");
1323 "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
1324}
#define INFINITE
Definition: serial.h:102
static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1262
static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1255
static HANDLE complete_event
Definition: url.c:179
#define WT_EXECUTEONLYONCE
Definition: winnt_old.h:1071

Referenced by START_TEST().

◆ test_reserved_tls()

static void test_reserved_tls ( void  )
static

Definition at line 1922 of file thread.c.

1923{
1924 void *val;
1925 DWORD tls;
1926 BOOL ret;
1927
1928 /* This seems to be a WinXP SP2+ feature. */
1929 if(!pIsWow64Process) {
1930 win_skip("Skipping reserved TLS slot on too old Windows.\n");
1931 return;
1932 }
1933
1934 val = TlsGetValue(0);
1935 ok(!val, "TlsGetValue(0) = %p\n", val);
1936
1937 /* Also make sure that there is a TLS allocated. */
1938 tls = TlsAlloc();
1939 ok(tls && tls != TLS_OUT_OF_INDEXES, "tls = %x\n", tls);
1940 TlsSetValue(tls, (void*)1);
1941
1942 val = TlsGetValue(0);
1943 ok(!val, "TlsGetValue(0) = %p\n", val);
1944
1945 TlsFree(tls);
1946
1947 /* The following is too ugly to be run by default */
1948 if(0) {
1949 /* Set TLS index 0 value and see that this works and doesn't cause problems
1950 * for remaining tests. */
1951 ret = TlsSetValue(0, (void*)1);
1952 ok(ret, "TlsSetValue(0, 1) failed: %u\n", GetLastError());
1953
1954 val = TlsGetValue(0);
1955 ok(val == (void*)1, "TlsGetValue(0) = %p\n", val);
1956 }
1957}
LPVOID WINAPI TlsGetValue(IN DWORD Index)
Definition: thread.c:1240
BOOL WINAPI TlsSetValue(IN DWORD Index, IN LPVOID Value)
Definition: thread.c:1276
static DWORD tls
Definition: sock.c:229

Referenced by START_TEST().

◆ test_SuspendThread()

static VOID test_SuspendThread ( void  )
static

Definition at line 554 of file thread.c.

555{
556 HANDLE thread,access_thread;
557 DWORD threadId,exitCode,error;
558 int i;
559
561 0,&threadId);
562 ok(thread!=NULL,"Create Thread failed\n");
563/* Check that the thread is suspended */
564/* Note that this is a polling method, and there is a race between
565 SuspendThread being called (in the child, and the loop below timing out,
566 so the test could fail on a heavily loaded or slow computer.
567*/
568 error=0;
569 for(i=0;error==0 && i<100;i++) {
572 if(error==0) {
573 Sleep(50);
574 i++;
575 }
576 }
577 ok(error==1,"SuspendThread did not work\n");
578/* check that access restrictions are obeyed */
579 if (pOpenThread) {
580 access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_SUSPEND_RESUME),
581 0,threadId);
582 ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
583 if (access_thread!=NULL) {
584 obey_ar(SuspendThread(access_thread)==~0U);
585 obey_ar(ResumeThread(access_thread)==~0U);
586 ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
587 }
588 }
589/* Double check that the thread really is suspended */
590 ok((error=GetExitCodeThread(thread,&exitCode))!=0 && exitCode==STILL_ACTIVE,
591 "Thread did not really suspend\n");
592/* Resume the thread, and make sure it actually completes */
593 ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
595 "Thread did not resume\n");
596 if(error!=WAIT_OBJECT_0) {
598 }
599 /* Trying to suspend a terminated thread should fail */
601 ok(error==~0U, "wrong return code: %d\n", error);
602 ok(GetLastError()==ERROR_ACCESS_DENIED || GetLastError()==ERROR_NO_MORE_ITEMS, "unexpected error code: %d\n", GetLastError());
603
604 ok(CloseHandle(thread)!=0,"CloseHandle Failed\n");
605}
#define U(x)
Definition: wordpad.c:45
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define THREAD_SUSPEND_RESUME
static DWORD WINAPI threadFunc3(LPVOID p)
Definition: thread.c:245
#define STILL_ACTIVE
Definition: winbase.h:259

Referenced by START_TEST().

◆ test_TerminateThread()

static VOID test_TerminateThread ( void  )
static

Definition at line 609 of file thread.c.

610{
611 HANDLE thread,access_thread,event;
612 DWORD threadId,exitCode;
614 thread = CreateThread(NULL,0,threadFunc4,event,0,&threadId);
615 ok(thread!=NULL,"Create Thread failed\n");
616/* TerminateThread has a race condition in Wine. If the thread is terminated
617 before it starts, it leaves a process behind. Therefore, we wait for the
618 thread to signal that it has started. There is no easy way to force the
619 race to occur, so we don't try to find it.
620*/
622 "TerminateThread didn't work\n");
623/* check that access restrictions are obeyed */
624 if (pOpenThread) {
625 access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 & (~THREAD_TERMINATE),
626 0,threadId);
627 ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
628 if (access_thread!=NULL) {
629 obey_ar(TerminateThread(access_thread,99)==0);
630 ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
631 }
632 }
633/* terminate a job and make sure it terminates */
634 ok(TerminateThread(thread,99)!=0,"TerminateThread failed\n");
636 "TerminateThread didn't work\n");
638 "TerminateThread should not leave the thread 'STILL_ACTIVE'\n");
639 ok(exitCode==99, "TerminateThread returned invalid exit code\n");
640 ok(CloseHandle(thread)!=0,"Error Closing thread handle\n");
641}
static DWORD WINAPI threadFunc4(LPVOID p)
Definition: thread.c:253
#define THREAD_TERMINATE
Definition: nt_native.h:1336

Referenced by START_TEST().

◆ test_thread_actctx()

static void test_thread_actctx ( void  )
static

Definition at line 1812 of file thread.c.

1813{
1817 DWORD tid, ret;
1818 BOOL b;
1819
1820 if (!pActivateActCtx)
1821 {
1822 win_skip("skipping activation context tests\n");
1823 return;
1824 }
1825
1826 create_manifest_file("testdep1.manifest", manifest_dep);
1827 create_manifest_file("main.manifest", manifest_main);
1828
1829 context = test_create("main.manifest");
1830 DeleteFileA("testdep1.manifest");
1831 DeleteFileA("main.manifest");
1832
1833 handle = (void*)0xdeadbeef;
1834 b = pGetCurrentActCtx(&handle);
1835 ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
1836 ok(handle == 0, "active context %p\n", handle);
1837
1838 /* without active context */
1839 param.thread_context = (void*)0xdeadbeef;
1840 param.handle = NULL;
1842 ok(thread != NULL, "failed, got %u\n", GetLastError());
1843
1845 ok(ret == WAIT_OBJECT_0, "wait timeout\n");
1846 ok(param.thread_context == NULL, "got wrong thread context %p\n", param.thread_context);
1848
1849 b = pActivateActCtx(context, &cookie);
1850 ok(b, "activation failed: %u\n", GetLastError());
1851
1852 handle = 0;
1853 b = pGetCurrentActCtx(&handle);
1854 ok(b, "GetCurrentActCtx failed: %u\n", GetLastError());
1855 ok(handle != 0, "no active context\n");
1856 pReleaseActCtx(handle);
1857
1858 param.handle = NULL;
1859 b = pGetCurrentActCtx(&param.handle);
1860 ok(b && param.handle != NULL, "failed to get context, %u\n", GetLastError());
1861
1862 param.thread_context = (void*)0xdeadbeef;
1864 ok(thread != NULL, "failed, got %u\n", GetLastError());
1865
1867 ok(ret == WAIT_OBJECT_0, "wait timeout\n");
1868 ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
1869 pReleaseActCtx(param.thread_context);
1871
1872 /* similar test for CreateRemoteThread() */
1873 param.thread_context = (void*)0xdeadbeef;
1875 ok(thread != NULL, "failed, got %u\n", GetLastError());
1876
1878 ok(ret == WAIT_OBJECT_0, "wait timeout\n");
1879 ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
1880 pReleaseActCtx(param.thread_context);
1882
1883 pReleaseActCtx(param.handle);
1884
1885 b = pDeactivateActCtx(0, cookie);
1886 ok(b, "DeactivateActCtx failed: %u\n", GetLastError());
1887 pReleaseActCtx(context);
1888}
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat param
Definition: glext.h:5796
#define b
Definition: ke_i.h:79
static void test_create(void)
Definition: monthcal.c:1595
static const char manifest_dep[]
Definition: thread.c:1756
static void create_manifest_file(const char *filename, const char *manifest)
Definition: thread.c:1772
static DWORD WINAPI thread_actctx_func(void *p)
Definition: thread.c:301
static const char manifest_main[]
Definition: thread.c:1762
Definition: http.c:7252
Definition: cookie.c:34
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by START_TEST().

◆ test_thread_info()

static void test_thread_info ( void  )
static

Definition at line 1959 of file thread.c.

1960{
1961 char buf[4096];
1962 static const ULONG info_size[] =
1963 {
1964 sizeof(THREAD_BASIC_INFORMATION), /* ThreadBasicInformation */
1965 sizeof(KERNEL_USER_TIMES), /* ThreadTimes */
1966 sizeof(ULONG), /* ThreadPriority */
1967 sizeof(ULONG), /* ThreadBasePriority */
1968 sizeof(ULONG_PTR), /* ThreadAffinityMask */
1969 sizeof(HANDLE), /* ThreadImpersonationToken */
1970 sizeof(THREAD_DESCRIPTOR_INFORMATION), /* ThreadDescriptorTableEntry */
1971 sizeof(BOOLEAN), /* ThreadEnableAlignmentFaultFixup */
1972 0, /* ThreadEventPair_Reusable */
1973 sizeof(ULONG_PTR), /* ThreadQuerySetWin32StartAddress */
1974 sizeof(ULONG), /* ThreadZeroTlsCell */
1975 sizeof(LARGE_INTEGER), /* ThreadPerformanceCount */
1976 sizeof(ULONG), /* ThreadAmILastThread */
1977 sizeof(ULONG), /* ThreadIdealProcessor */
1978 sizeof(ULONG), /* ThreadPriorityBoost */
1979 sizeof(ULONG_PTR), /* ThreadSetTlsArrayAddress */
1980 sizeof(ULONG), /* ThreadIsIoPending */
1981 sizeof(BOOLEAN), /* ThreadHideFromDebugger */
1982 /* FIXME: Add remaining classes */
1983 };
1984 HANDLE thread;
1986
1987 if (!pOpenThread)
1988 {
1989 win_skip("OpenThread is not available on this platform\n");
1990 return;
1991 }
1992
1993 if (!pNtQueryInformationThread)
1994 {
1995 win_skip("NtQueryInformationThread is not available on this platform\n");
1996 return;
1997 }
1998
2000 if (!thread)
2001 {
2002 win_skip("THREAD_QUERY_LIMITED_INFORMATION is not supported on this platform\n");
2003 return;
2004 }
2005
2006 for (i = 0; i < sizeof(info_size)/sizeof(info_size[0]); i++)
2007 {
2008 memset(buf, 0, sizeof(buf));
2009
2010#ifdef __i386__
2012 {
2013 CONTEXT ctx;
2014 THREAD_DESCRIPTOR_INFORMATION *tdi = (void *)buf;
2015
2016 ctx.ContextFlags = CONTEXT_SEGMENTS;
2018 tdi->Selector = ctx.SegDs;
2019 }
2020#endif
2021 ret_len = 0;
2022 status = pNtQueryInformationThread(thread, i, buf, info_size[i], &ret_len);
2023 if (status == STATUS_NOT_IMPLEMENTED) continue;
2024 if (status == STATUS_INVALID_INFO_CLASS) continue;
2025 if (status == STATUS_UNSUCCESSFUL) continue;
2026
2027 switch (i)
2028 {
2032 ok(status == STATUS_SUCCESS, "for info %u expected STATUS_SUCCESS, got %08x (ret_len %u)\n", i, status, ret_len);
2033 break;
2034
2035#ifdef __i386__
2037 ok(status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED) /* testbot VM is broken */,
2038 "for info %u expected STATUS_SUCCESS, got %08x (ret_len %u)\n", i, status, ret_len);
2039 break;
2040#endif
2041
2042 case ThreadTimes:
2044 ok(status == STATUS_SUCCESS, "for info %u expected STATUS_SUCCESS, got %08x (ret_len %u)\n", i, status, ret_len);
2045 break;
2046
2047 case ThreadAffinityMask:
2049 case ThreadIsIoPending:
2051 ok(status == STATUS_ACCESS_DENIED, "for info %u expected STATUS_ACCESS_DENIED, got %08x (ret_len %u)\n", i, status, ret_len);
2052 break;
2053
2054 default:
2055 ok(status == STATUS_ACCESS_DENIED, "for info %u expected STATUS_ACCESS_DENIED, got %08x (ret_len %u)\n", i, status, ret_len);
2056 break;
2057 }
2058 }
2059
2061}
unsigned char BOOLEAN
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
struct _THREAD_BASIC_INFORMATION THREAD_BASIC_INFORMATION
@ ThreadDescriptorTableEntry
Definition: compat.h:941
@ ThreadAmILastThread
Definition: compat.h:947
@ ThreadTimes
Definition: compat.h:936
@ ThreadQuerySetWin32StartAddress
Definition: compat.h:944
@ ThreadAffinityMask
Definition: compat.h:939
@ ThreadBasicInformation
Definition: compat.h:935
@ ThreadPriorityBoost
Definition: compat.h:949
@ ThreadIsIoPending
Definition: compat.h:951
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct _THREAD_DESCRIPTOR_INFORMATION THREAD_DESCRIPTOR_INFORMATION
#define THREAD_QUERY_LIMITED_INFORMATION
Definition: security.c:62
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:79
static ULONG
Definition: thread.c:78
static ULONG_PTR
Definition: thread.c:89
#define todo_wine
Definition: custom.c:89
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define BOOLEAN
Definition: pedump.c:73
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: ps.c:97
union _LARGE_INTEGER LARGE_INTEGER
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148

Referenced by START_TEST().

◆ test_thread_priority()

static VOID test_thread_priority ( void  )
static

Definition at line 673 of file thread.c.

674{
675 HANDLE curthread,access_thread;
676 DWORD curthreadId,exitCode;
677 int min_priority=-2,max_priority=2;
678 BOOL disabled,rc;
679 int i;
680
681 curthread=GetCurrentThread();
682 curthreadId=GetCurrentThreadId();
683/* Check thread priority */
684/* NOTE: on Win2k/XP priority can be from -7 to 6. All other platforms it
685 is -2 to 2. However, even on a real Win2k system, using thread
686 priorities beyond the -2 to 2 range does not work. If you want to try
687 anyway, enable USE_EXTENDED_PRIORITIES
688*/
690 "GetThreadPriority Failed\n");
691
692 if (pOpenThread) {
693/* check that access control is obeyed */
694 access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 &
696 0,curthreadId);
697 ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
698 if (access_thread!=NULL) {
699 obey_ar(SetThreadPriority(access_thread,1)==0);
701 obey_ar(GetExitCodeThread(access_thread,&exitCode)==0);
702 ok(CloseHandle(access_thread),"Error Closing thread handle\n");
703 }
704 }
705#if USE_EXTENDED_PRIORITIES
706 min_priority=-7; max_priority=6;
707#endif
708 for(i=min_priority;i<=max_priority;i++) {
709 ok(SetThreadPriority(curthread,i)!=0,
710 "SetThreadPriority Failed for priority: %d\n",i);
711 ok(GetThreadPriority(curthread)==i,
712 "GetThreadPriority Failed for priority: %d\n",i);
713 }
715 "SetThreadPriority Failed\n");
717 "GetThreadPriority Failed\n");
719 "SetThreadPriority Failed\n");
721 "GetThreadPriority Failed\n");
722 ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed\n");
723
724/* Check that the thread priority is not changed if SetThreadPriority
725 is called with a value outside of the max/min range */
726 SetThreadPriority(curthread,min_priority);
727 SetLastError(0xdeadbeef);
728 rc = SetThreadPriority(curthread,min_priority-1);
729
730 ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
732 GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
733 "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
734 GetLastError());
735 ok(GetThreadPriority(curthread)==min_priority,
736 "GetThreadPriority didn't return min_priority\n");
737
738 SetThreadPriority(curthread,max_priority);
739 SetLastError(0xdeadbeef);
740 rc = SetThreadPriority(curthread,max_priority+1);
741
742 ok(rc == FALSE, "SetThreadPriority passed with a bad argument\n");
744 GetLastError() == ERROR_INVALID_PRIORITY /* Win9x */,
745 "SetThreadPriority error %d, expected ERROR_INVALID_PARAMETER or ERROR_INVALID_PRIORITY\n",
746 GetLastError());
747 ok(GetThreadPriority(curthread)==max_priority,
748 "GetThreadPriority didn't return max_priority\n");
749
750/* Check thread priority boost */
751 if (!pGetThreadPriorityBoost || !pSetThreadPriorityBoost)
752 return; /* Win9x */
753
754 SetLastError(0xdeadbeef);
755 rc=pGetThreadPriorityBoost(curthread,&disabled);
757 {
758 win_skip("GetThreadPriorityBoost is not implemented on WinME\n");
759 return;
760 }
761
762 ok(rc!=0,"error=%d\n",GetLastError());
763
764 if (pOpenThread) {
765/* check that access control is obeyed */
766 access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 &
768 0,curthreadId);
769 ok(access_thread!=NULL,"OpenThread returned an invalid handle\n");
770 if (access_thread!=NULL) {
771 todo_wine obey_ar(pSetThreadPriorityBoost(access_thread,1)==0);
772 todo_wine obey_ar(pGetThreadPriorityBoost(access_thread,&disabled)==0);
773 ok(CloseHandle(access_thread),"Error Closing thread handle\n");
774 }
775 }
776
777 rc = pSetThreadPriorityBoost(curthread,1);
778 ok( rc != 0, "error=%d\n",GetLastError());
779 todo_wine {
780 rc=pGetThreadPriorityBoost(curthread,&disabled);
781 ok(rc!=0 && disabled==1,
782 "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
783 }
784
785 rc = pSetThreadPriorityBoost(curthread,0);
786 ok( rc != 0, "error=%d\n",GetLastError());
787 rc=pGetThreadPriorityBoost(curthread,&disabled);
788 ok(rc!=0 && disabled==0,
789 "rc=%d error=%d disabled=%d\n",rc,GetLastError(),disabled);
790}
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
int WINAPI GetThreadPriority(IN HANDLE hThread)
Definition: thread.c:739
#define THREAD_SET_INFORMATION
Definition: nt_native.h:1337
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:307
#define THREAD_PRIORITY_ERROR_RETURN
Definition: winbase.h:308
#define THREAD_PRIORITY_NORMAL
Definition: winbase.h:306
#define THREAD_PRIORITY_IDLE
Definition: winbase.h:304
#define ERROR_INVALID_PRIORITY
Definition: winerror.h:1107

Referenced by START_TEST().

◆ test_thread_processor()

static VOID test_thread_processor ( void  )
static

Definition at line 850 of file thread.c.

851{
852 HANDLE curthread,curproc;
853 DWORD_PTR processMask,systemMask,retMask;
854 SYSTEM_INFO sysInfo;
855 int error=0;
857
858 if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
859
860 sysInfo.dwNumberOfProcessors=0;
861 GetSystemInfo(&sysInfo);
862 ok(sysInfo.dwNumberOfProcessors>0,
863 "GetSystemInfo failed to return a valid # of processors\n");
864/* Use the current Thread/process for all tests */
865 curthread=GetCurrentThread();
866 ok(curthread!=NULL,"GetCurrentThread failed\n");
867 curproc=GetCurrentProcess();
868 ok(curproc!=NULL,"GetCurrentProcess failed\n");
869/* Check the Affinity Mask functions */
870 ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
871 "GetProcessAffinityMask failed\n");
872 ok(SetThreadAffinityMask(curthread,processMask)==processMask,
873 "SetThreadAffinityMask failed\n");
874 ok(SetThreadAffinityMask(curthread,processMask+1)==0,
875 "SetThreadAffinityMask passed for an illegal processor\n");
876/* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
877 retMask = SetThreadAffinityMask(curthread,~0);
878 ok(broken(retMask==0) || retMask==processMask,
879 "SetThreadAffinityMask(thread,-1) failed to request all processors.\n");
880
881 if (retMask == processMask)
882 {
883 /* Show that the "all processors" flag is handled in ntdll */
884 DWORD_PTR mask = ~0u;
885 NTSTATUS status = pNtSetInformationThread(curthread, ThreadAffinityMask, &mask, sizeof(mask));
886 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS in NtSetInformationThread, got %x\n", status);
887 }
888
889 if (retMask == processMask && sizeof(ULONG_PTR) > sizeof(ULONG))
890 {
891 /* only the low 32-bits matter */
892 retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0);
893 ok(retMask == processMask, "SetThreadAffinityMask failed\n");
894 retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0 >> 3);
895 ok(retMask == processMask, "SetThreadAffinityMask failed\n");
896 }
897/* NOTE: This only works on WinNT/2000/XP) */
898 if (pSetThreadIdealProcessor)
899 {
900 SetLastError(0xdeadbeef);
901 error=pSetThreadIdealProcessor(curthread,0);
903 {
904 ok(error!=-1, "SetThreadIdealProcessor failed\n");
905
906 if (is_wow64)
907 {
908 SetLastError(0xdeadbeef);
909 error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
911 ok(error!=-1, "SetThreadIdealProcessor failed for %u on Wow64\n", MAXIMUM_PROCESSORS+1);
912
913 SetLastError(0xdeadbeef);
914 error=pSetThreadIdealProcessor(curthread,65);
915 ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
917 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
918 }
919 else
920 {
921 SetLastError(0xdeadbeef);
922 error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
923 ok(error==-1, "SetThreadIdealProcessor succeeded with an illegal processor #\n");
925 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
926 }
927
928 error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
929 ok(error!=-1, "SetThreadIdealProcessor failed\n");
930 }
931 else
932 win_skip("SetThreadIdealProcessor is not implemented\n");
933 }
934
935 if (pGetThreadGroupAffinity && pSetThreadGroupAffinity)
936 {
937 GROUP_AFFINITY affinity, affinity_new;
939
940 memset(&affinity, 0, sizeof(affinity));
941 ok(pGetThreadGroupAffinity(curthread, &affinity), "GetThreadGroupAffinity failed\n");
942
943 SetLastError(0xdeadbeef);
944 ok(!pGetThreadGroupAffinity(curthread, NULL), "GetThreadGroupAffinity succeeded\n");
946 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
947 ok(affinity.Group == 0, "Expected group 0 got %u\n", affinity.Group);
948
949 memset(&affinity_new, 0, sizeof(affinity_new));
950 affinity_new.Group = 0;
951 affinity_new.Mask = affinity.Mask;
952 ok(pSetThreadGroupAffinity(curthread, &affinity_new, &affinity), "SetThreadGroupAffinity failed\n");
953 ok(affinity_new.Mask == affinity.Mask, "Expected old affinity mask %lx, got %lx\n",
954 affinity_new.Mask, affinity.Mask);
955
956 /* show that the "all processors" flag is not supported for SetThreadGroupAffinity */
957 affinity_new.Group = 0;
958 affinity_new.Mask = ~0u;
959 SetLastError(0xdeadbeef);
960 ok(!pSetThreadGroupAffinity(curthread, &affinity_new, NULL), "SetThreadGroupAffinity succeeded\n");
962 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
963
964 affinity_new.Group = 1; /* assumes that you have less than 64 logical processors */
965 affinity_new.Mask = 0x1;
966 SetLastError(0xdeadbeef);
967 ok(!pSetThreadGroupAffinity(curthread, &affinity_new, NULL), "SetThreadGroupAffinity succeeded\n");
969 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
970
971 SetLastError(0xdeadbeef);
972 ok(!pSetThreadGroupAffinity(curthread, NULL, NULL), "SetThreadGroupAffinity succeeded\n");
974 "Expected ERROR_NOACCESS, got %d\n", GetLastError());
975
976 /* show that the access violation was detected in ntdll */
977 status = pNtSetInformationThread(curthread, ThreadGroupInformation, NULL, sizeof(affinity_new));
979 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
980
981 /* restore original mask */
982 affinity_new.Group = 0;
983 affinity_new.Mask = affinity.Mask;
984 SetLastError(0xdeadbeef);
985 ok(pSetThreadGroupAffinity(curthread, &affinity_new, &affinity), "SetThreadGroupAffinity failed\n");
986 ok(affinity_new.Mask == affinity.Mask, "Expected old affinity mask %lx, got %lx\n",
987 affinity_new.Mask, affinity.Mask);
988 }
989 else
990 win_skip("Get/SetThreadGroupAffinity not available\n");
991}
LONG NTSTATUS
Definition: precomp.h:26
@ ThreadGroupInformation
Definition: compat.h:965
BOOL WINAPI GetProcessAffinityMask(IN HANDLE hProcess, OUT PDWORD_PTR lpProcessAffinityMask, OUT PDWORD_PTR lpSystemAffinityMask)
Definition: proc.c:863
DWORD_PTR WINAPI SetThreadAffinityMask(IN HANDLE hThread, IN DWORD_PTR dwThreadAffinityMask)
Definition: thread.c:662
BOOL is_wow64
Definition: msi.c:52
KAFFINITY affinity
Definition: wave.h:2
#define MAXIMUM_PROCESSORS
Definition: rwlock.h:5
GLenum GLint GLuint mask
Definition: glext.h:6028
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
$USHORT Group
Definition: ntbasedef.h:669
KAFFINITY Mask
Definition: ntbasedef.h:668
DWORD dwNumberOfProcessors
Definition: winbase.h:1202
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define ERROR_NOACCESS
Definition: winerror.h:578

Referenced by START_TEST().

◆ test_ThreadErrorMode()

static void test_ThreadErrorMode ( void  )
static

Definition at line 1574 of file thread.c.

1575{
1576 DWORD oldmode;
1577 DWORD mode;
1578 DWORD rtlmode;
1579 BOOL ret;
1580
1581 if (!pSetThreadErrorMode || !pGetThreadErrorMode)
1582 {
1583 win_skip("SetThreadErrorMode and/or GetThreadErrorMode unavailable (added in Windows 7)\n");
1584 return;
1585 }
1586
1587 if (!pRtlGetThreadErrorMode) {
1588 win_skip("RtlGetThreadErrorMode not available\n");
1589 return;
1590 }
1591
1592 oldmode = pGetThreadErrorMode();
1593
1594 ret = pSetThreadErrorMode(0, &mode);
1595 ok(ret, "SetThreadErrorMode failed\n");
1596 ok(mode == oldmode,
1597 "SetThreadErrorMode returned old mode 0x%x, expected 0x%x\n",
1598 mode, oldmode);
1599 mode = pGetThreadErrorMode();
1600 ok(mode == 0, "GetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1601 rtlmode = pRtlGetThreadErrorMode();
1602 ok(rtlmode == 0,
1603 "RtlGetThreadErrorMode returned mode 0x%x, expected 0\n", mode);
1604
1605 ret = pSetThreadErrorMode(SEM_FAILCRITICALERRORS, &mode);
1606 ok(ret, "SetThreadErrorMode failed\n");
1607 ok(mode == 0,
1608 "SetThreadErrorMode returned old mode 0x%x, expected 0\n", mode);
1609 mode = pGetThreadErrorMode();
1611 "GetThreadErrorMode returned mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1612 mode);
1613 rtlmode = pRtlGetThreadErrorMode();
1614 ok(rtlmode == 0x10,
1615 "RtlGetThreadErrorMode returned mode 0x%x, expected 0x10\n", mode);
1616
1617 ret = pSetThreadErrorMode(SEM_NOGPFAULTERRORBOX, &mode);
1618 ok(ret, "SetThreadErrorMode failed\n");
1620 "SetThreadErrorMode returned old mode 0x%x, expected SEM_FAILCRITICALERRORS\n",
1621 mode);
1622 mode = pGetThreadErrorMode();
1624 "GetThreadErrorMode returned mode 0x%x, expected SEM_NOGPFAULTERRORBOX\n",
1625 mode);
1626 rtlmode = pRtlGetThreadErrorMode();
1627 ok(rtlmode == 0x20,
1628 "RtlGetThreadErrorMode returned mode 0x%x, expected 0x20\n", mode);
1629
1630 ret = pSetThreadErrorMode(SEM_NOOPENFILEERRORBOX, NULL);
1631 ok(ret, "SetThreadErrorMode failed\n");
1632 mode = pGetThreadErrorMode();
1634 "GetThreadErrorMode returned mode 0x%x, expected SEM_NOOPENFILEERRORBOX\n",
1635 mode);
1636 rtlmode = pRtlGetThreadErrorMode();
1637 ok(rtlmode == 0x40,
1638 "RtlGetThreadErrorMode returned mode 0x%x, expected 0x40\n", rtlmode);
1639
1640 for (mode = 1; mode; mode <<= 1)
1641 {
1642 ret = pSetThreadErrorMode(mode, NULL);
1646 {
1647 ok(ret,
1648 "SetThreadErrorMode(0x%x,NULL) failed with error %d\n",
1649 mode, GetLastError());
1650 }
1651 else
1652 {
1654 ok(!ret,
1655 "SetThreadErrorMode(0x%x,NULL) succeeded, expected failure\n",
1656 mode);
1658 "SetThreadErrorMode(0x%x,NULL) failed with %d, "
1659 "expected ERROR_INVALID_PARAMETER\n",
1660 mode, GLE);
1661 }
1662 }
1663
1664 pSetThreadErrorMode(oldmode, NULL);
1665}
GLenum mode
Definition: glext.h:6217
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define SEM_NOGPFAULTERRORBOX
Definition: rtltypes.h:70
#define SEM_NOOPENFILEERRORBOX
Definition: rtltypes.h:72

Referenced by START_TEST().

◆ test_threadpool()

static void test_threadpool ( void  )
static

Definition at line 1898 of file thread.c.

1899{
1900 PTP_POOL pool;
1901 PTP_WORK work;
1902 int workcalled = 0;
1903
1904 if (!pCreateThreadpool) {
1905 win_skip("thread pool apis not supported.\n");
1906 return;
1907 }
1908
1909 work = pCreateThreadpoolWork(threadpool_workcallback, &workcalled, NULL);
1910 ok (work != NULL, "Error %d in CreateThreadpoolWork\n", GetLastError());
1911 pSubmitThreadpoolWork(work);
1912 pWaitForThreadpoolWorkCallbacks(work, FALSE);
1913 pCloseThreadpoolWork(work);
1914
1915 ok (workcalled == 1, "expected work to be called once, got %d\n", workcalled);
1916
1917 pool = pCreateThreadpool(NULL);
1918 ok (pool != NULL, "CreateThreadpool failed\n");
1919 pCloseThreadpool(pool);
1920}
static void WINAPI threadpool_workcallback(PTP_CALLBACK_INSTANCE instance, void *context, PTP_WORK work)
Definition: thread.c:1891
struct _TP_WORK * PTP_WORK
Definition: winnt_old.h:4481
struct _TP_POOL * PTP_POOL
Definition: winnt_old.h:4480

Referenced by START_TEST().

◆ test_TLS()

static void test_TLS ( void  )
static

Definition at line 1534 of file thread.c.

1535{
1537
1538 LS_AllocFunc = &TlsAlloc;
1539 LS_GetValueFunc = &TlsGetValue;
1540 LS_SetValueFunc = &TlsSetValue;
1541 LS_FreeFunc = &TlsFree;
1542
1543 LS_AllocFuncName = "TlsAlloc";
1544 LS_GetValueFuncName = "TlsGetValue";
1545 LS_SetValueFuncName = "TlsSetValue";
1546 LS_FreeFuncName = "TlsFree";
1547
1548 run_LS_tests();
1549}

Referenced by START_TEST().

◆ thread_actctx_func()

static DWORD WINAPI thread_actctx_func ( void p)
static

Definition at line 301 of file thread.c.

302{
304 HANDLE cur;
305 BOOL ret;
306
307 cur = (void*)0xdeadbeef;
308 ret = pGetCurrentActCtx(&cur);
309 ok(ret, "thread GetCurrentActCtx failed, %u\n", GetLastError());
310 ok(cur == param->handle, "got %p, expected %p\n", cur, param->handle);
311 param->thread_context = cur;
312
313 return 0;
314}
FxCollectionEntry * cur

Referenced by test_thread_actctx().

◆ threadFunc1()

static DWORD WINAPI threadFunc1 ( LPVOID  p)
static

Definition at line 212 of file thread.c.

213{
214 t1Struct *tstruct = p;
215 int i;
216/* write our thread # into shared memory */
217 tstruct->threadmem[tstruct->threadnum]=GetCurrentThreadId();
218 ok(TlsSetValue(tlsIndex,(LPVOID)(INT_PTR)(tstruct->threadnum+1))!=0,
219 "TlsSetValue failed\n");
220/* The threads synchronize before terminating. This is done by
221 Signaling an event, and waiting for all events to occur
222*/
223 SetEvent(tstruct->event[tstruct->threadnum]);
225/* Double check that all threads really did run by validating that
226 they have all written to the shared memory. There should be no race
227 here, since all threads were synchronized after the write.*/
228 for (i = 0; i < NUM_THREADS; i++)
229 ok(tstruct->threadmem[i] != 0, "expected threadmem[%d] != 0\n", i);
230
231 /* lstrlenA contains an exception handler so this makes sure exceptions work in threads */
232 ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
233
234/* Check that no one changed our tls memory */
236 "TlsGetValue failed\n");
237 return NUM_THREADS+tstruct->threadnum;
238}

Referenced by test_CreateThread_basic().

◆ threadFunc2()

static DWORD WINAPI threadFunc2 ( LPVOID  p)
static

Definition at line 240 of file thread.c.

241{
242 return 99;
243}

Referenced by START_TEST(), test_CreateThread_basic(), test_CreateThread_suspended(), test_GetThreadExitCode(), and test_GetThreadTimes().

◆ threadFunc3()

static DWORD WINAPI threadFunc3 ( LPVOID  p)
static

Definition at line 245 of file thread.c.

246{
250 return 99;
251}

Referenced by test_SuspendThread().

◆ threadFunc4()

static DWORD WINAPI threadFunc4 ( LPVOID  p)
static

Definition at line 253 of file thread.c.

254{
255 HANDLE event = p;
256 if(event != NULL) {
258 }
259 Sleep(99000);
260 return 0;
261}

Referenced by test_TerminateThread().

◆ threadFunc_CloseHandle()

static DWORD WINAPI threadFunc_CloseHandle ( LPVOID  p)
static

Definition at line 289 of file thread.c.

290{
291 CloseHandle(p);
292 return 0;
293}

Referenced by create_function_addr_events(), and test_CreateRemoteThread().

◆ threadFunc_SetEvent()

static DWORD WINAPI threadFunc_SetEvent ( LPVOID  p)
static

Definition at line 283 of file thread.c.

284{
285 SetEvent(p);
286 return 0;
287}

Referenced by create_function_addr_events(), and test_CreateRemoteThread().

◆ threadpool_workcallback()

static void WINAPI threadpool_workcallback ( PTP_CALLBACK_INSTANCE  instance,
void context,
PTP_WORK  work 
)
static

Definition at line 1891 of file thread.c.

1891 {
1892 int *foo = (int*)context;
1893
1894 (*foo)++;
1895}

Referenced by test_threadpool().

◆ timeout_function()

static void CALLBACK timeout_function ( PVOID  p,
BOOLEAN  TimerOrWaitFired 
)
static

Definition at line 1262 of file thread.c.

1263{
1264 HANDLE event = p;
1265 SetEvent(event);
1266 ok(TimerOrWaitFired, "wait should have timed out\n");
1267}

Referenced by test_RegisterWaitForSingleObject().

◆ void()

static void ( WINAPI pReleaseActCtx)
static

◆ work_function()

static DWORD CALLBACK work_function ( void p)
static

Definition at line 1218 of file thread.c.

1219{
1221
1222 if (executed == 100)
1224 return 0;
1225}

Referenced by test_QueueUserWorkItem().

Variable Documentation

◆ BOOL

Definition at line 77 of file thread.c.

◆ DWORD

Definition at line 77 of file thread.c.

◆ finish_event

HANDLE finish_event
static

Definition at line 1215 of file thread.c.

Referenced by test_QueueUserWorkItem(), and work_function().

◆ HANDLE

Definition at line 81 of file thread.c.

◆ LPCVOID

Definition at line 101 of file thread.c.

◆ LS_AllocFuncName

const char* LS_AllocFuncName = ""
static

Definition at line 1337 of file thread.c.

Referenced by LS_ThreadProc(), run_LS_tests(), test_FLS(), and test_TLS().

◆ LS_FreeFuncName

const char* LS_FreeFuncName = ""
static

Definition at line 1340 of file thread.c.

Referenced by LS_ThreadProc(), run_LS_tests(), test_FLS(), and test_TLS().

◆ LS_GetValueFuncName

const char* LS_GetValueFuncName = ""
static

Definition at line 1338 of file thread.c.

Referenced by LS_InheritanceProc(), LS_ThreadProc(), test_FLS(), and test_TLS().

◆ LS_index0

DWORD LS_index0
static

Definition at line 1327 of file thread.c.

Referenced by LS_InheritanceProc(), and LS_ThreadProc().

◆ LS_index1

DWORD LS_index1
static

Definition at line 1327 of file thread.c.

Referenced by LS_InheritanceProc(), and LS_ThreadProc().

◆ LS_main

DWORD LS_main
static

Definition at line 1326 of file thread.c.

Referenced by LS_InheritanceProc(), and run_LS_tests().

◆ LS_OutOfIndexesValue

DWORD LS_OutOfIndexesValue
static

Definition at line 1328 of file thread.c.

Referenced by LS_ThreadProc(), run_LS_tests(), test_FLS(), and test_TLS().

◆ LS_SetValueFuncName

const char* LS_SetValueFuncName = ""
static

Definition at line 1339 of file thread.c.

Referenced by LS_ThreadProc(), run_LS_tests(), test_FLS(), and test_TLS().

◆ manifest_dep

const char manifest_dep[]
static
Initial value:
=
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
"<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
" <file name=\"testdep.dll\" />"
"</assembly>"
#define ARCH
Definition: thread.c:73

Definition at line 1756 of file thread.c.

Referenced by test_thread_actctx().

◆ manifest_main

const char manifest_main[]
static
Initial value:
=
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
"<dependency>"
" <dependentAssembly>"
" <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
" </dependentAssembly>"
"</dependency>"
"</assembly>"

Definition at line 1762 of file thread.c.

Referenced by test_thread_actctx().

◆ num_synced

LONG num_synced
static

Definition at line 136 of file thread.c.

Referenced by init_thread_sync_helpers(), resync_after_run(), and sync_threads_and_run_one().

◆ obeying_ars

INT obeying_ars = 0
static

Definition at line 197 of file thread.c.

◆ PBOOL

Definition at line 76 of file thread.c.

◆ PDWORD

Definition at line 84 of file thread.c.

◆ PTP_CALLBACK_ENVIRON

Definition at line 94 of file thread.c.

◆ PULONG

Definition at line 98 of file thread.c.

◆ PVOID

◆ start_event

◆ stop_event

◆ THREADINFOCLASS

Definition at line 98 of file thread.c.

◆ times_executed

LONG times_executed
static

Definition at line 1216 of file thread.c.

Referenced by test_QueueUserWorkItem(), and work_function().

◆ tlsIndex

DWORD tlsIndex
static

Definition at line 186 of file thread.c.

Referenced by test_CreateThread_basic(), and threadFunc1().

◆ ULONG

Definition at line 78 of file thread.c.

Referenced by PspUserThreadStartup(), RtlInitializeContext(), and test_thread_info().

◆ ULONG_PTR

Definition at line 89 of file thread.c.

Referenced by test_thread_info().

◆ WAITORTIMERCALLBACK

WAITORTIMERCALLBACK

Definition at line 81 of file thread.c.

Referenced by test_pack_WAITORTIMERCALLBACK().