ReactOS 0.4.16-dev-2208-g6350669
thread.c File Reference
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <float.h>
#include <math.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
 
struct  waitthread_test_param
 
struct  unregister_params
 
struct  fpu_thread_ctx
 
struct  tagTHREADNAME_INFO
 

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)
 

Typedefs

typedef struct tagTHREADNAME_INFO THREADNAME_INFO
 

Functions

static void (WINAPI *pGetCurrentThreadStackLimits)(PULONG_PTR
 
static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE
 
static HANDLE (WINAPI *pOpenThread)(DWORD
 
static DWORD (WINAPI *pGetThreadErrorMode)(void)
 
static PTP_POOL (WINAPI *pCreateThreadpool)(PVOID)
 
static PTP_WORK (WINAPI *pCreateThreadpoolWork)(PTP_WORK_CALLBACK
 
static NTSTATUS (WINAPI *pNtQueryInformationThread)(HANDLE
 
static HRESULT (WINAPI *pSetThreadDescription)(HANDLE
 
static const WCHAR *static WCHAR **static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG
 
static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID)
 
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_GetCurrentThreadStackLimits (void)
 
static void test_SetThreadStackGuarantee (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 wait_complete_function (PVOID p, BOOLEAN TimerOrWaitFired)
 
static void CALLBACK timeout_function (PVOID p, BOOLEAN TimerOrWaitFired)
 
static void CALLBACK waitthread_test_function (PVOID p, BOOLEAN TimerOrWaitFired)
 
static void CALLBACK unregister_function (PVOID p, BOOLEAN TimerOrWaitFired)
 
static void test_RegisterWaitForSingleObject (void)
 
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 unsigned long get_fpu_cw (void)
 
static void fpu_invalid_operation (void)
 
static DWORD WINAPI fpu_thread (void *param)
 
static unsigned int get_thread_fpu_cw (unsigned long *fpu_cw)
 
static void test_thread_fpu_cw (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 LONG CALLBACK msvc_threadname_vec_handler (EXCEPTION_POINTERS *ExceptionInfo)
 
static void test_thread_description (void)
 
static void init_funcs (void)
 
 START_TEST (thread)
 

Variables

static PULONG_PTR
 
static PBOOL
 
static BOOL
 
static DWORD
 
static PVOID
 
static ULONG
 
static HANDLE
 
static WAITORTIMERCALLBACK
 
static PDWORD
 
static PTP_CALLBACK_ENVIRON
 
static THREADINFOCLASS
 
static PULONG
 
static GROUP_AFFINITY *static const GROUP_AFFINITY GROUP_AFFINITY *static LPCVOID
 
static const WCHAR *static WCHAR **static PVECTORED_EXCEPTION_HANDLER
 
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 75 of file thread.c.

◆ CHECK_STACK

#define CHECK_STACK   0

Definition at line 48 of file thread.c.

◆ NUM_THREADS

#define NUM_THREADS   4

Definition at line 44 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:198

Definition at line 199 of file thread.c.

◆ THREAD_ALL_ACCESS_NT4

#define THREAD_ALL_ACCESS_NT4   (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)

Definition at line 41 of file thread.c.

◆ USE_EXTENDED_PRIORITIES

#define USE_EXTENDED_PRIORITIES   0

Definition at line 46 of file thread.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 31 of file thread.c.

◆ WINE_NO_INLINE_STRING

#define WINE_NO_INLINE_STRING

Definition at line 28 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)

Typedef Documentation

◆ THREADNAME_INFO

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pGetThreadPriorityBoost)
static

◆ cleanup_thread_sync_helpers()

static void cleanup_thread_sync_helpers ( void  )
static

Definition at line 181 of file thread.c.

182{
185}
#define CloseHandle
Definition: compat.h:739
static HANDLE stop_event
Definition: thread.c:136
static HANDLE start_event
Definition: thread.c:136

Referenced by run_LS_tests().

◆ create_function_addr_events()

static void create_function_addr_events ( HANDLE  events[2])
static

Definition at line 317 of file thread.c.

318{
319 char buffer[256];
320
321 sprintf(buffer, "threadFunc_SetEvent %p", threadFunc_SetEvent);
323
324 sprintf(buffer, "threadFunc_CloseHandle %p", threadFunc_CloseHandle);
326}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
GLuint buffer
Definition: glext.h:5915
#define sprintf
Definition: sprintf.c:45
HANDLE events[2]
Definition: event.c:4
static DWORD WINAPI threadFunc_SetEvent(LPVOID p)
Definition: thread.c:284
static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
Definition: thread.c:290
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 2090 of file thread.c.

2091{
2093 HANDLE file;
2094 DWORD size;
2095
2098 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError());
2101}
#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
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
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 105 of file thread.c.

106{
107 char **argv;
108 char cmdline[MAX_PATH];
110 BOOL ret;
111 STARTUPINFOA si = { 0 };
112 si.cb = sizeof(si);
113
115 sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
117 ok(ret, "error: %lu\n", GetLastError());
119 ok(ret, "error %lu\n", GetLastError());
120 return pi.hProcess;
121}
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:4749
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static SYSTEM_INFO si
Definition: virtual.c:39
#define argv
Definition: mplay32.c:18
int winetest_get_mainargs(char ***pargv)
TCHAR * cmdline
Definition: stretchblt.cpp:32

Referenced by test_CreateRemoteThread().

◆ DWORD()

static DWORD ( WINAPI pGetThreadErrorMode)
static

◆ FLS_AllocFuncThunk()

static DWORD WINAPI FLS_AllocFuncThunk ( void  )
static

Definition at line 1570 of file thread.c.

1571{
1572 return pFlsAlloc(NULL);
1573}

Referenced by test_FLS().

◆ fpu_invalid_operation()

static void fpu_invalid_operation ( void  )
inlinestatic

Definition at line 1928 of file thread.c.

1929{
1930 double d;
1931
1932#if defined(__i386__)
1933 unsigned int sse;
1934#ifdef _MSC_VER
1935 __asm { stmxcsr [sse] }
1936 sse |= 1; /* invalid operation flag */
1937 __asm { ldmxcsr [sse] }
1938#else
1939 __asm__ volatile ("stmxcsr %0" : "=m" (sse));
1940 sse |= 1;
1941 __asm__ volatile ("ldmxcsr %0" : : "m" (sse));
1942#endif
1943#endif
1944
1945 d = acos(2.0);
1946 ok(_isnan(d), "d = %lf\n", d);
1947 ok(_statusfp() & _SW_INVALID, "_statusfp() = %x\n", _statusfp());
1948}
_ACRTIMP unsigned int __cdecl _statusfp(void)
Definition: math.c:1156
_ACRTIMP int __cdecl _isnan(double)
Definition: math.c:1660
#define _SW_INVALID
Definition: float.h:97
_ACRTIMP double __cdecl acos(double)
Definition: acos.c:28
#define d
Definition: ke_i.h:81
@ sse
Definition: optimize.h:107
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")

Referenced by test_thread_fpu_cw().

◆ fpu_thread()

static DWORD WINAPI fpu_thread ( void param)
static

Definition at line 1950 of file thread.c.

1951{
1952 struct fpu_thread_ctx *ctx = param;
1953 BOOL ret;
1954
1955 ctx->cw = _control87( 0, 0 );
1956 ctx->fpu_cw = get_fpu_cw();
1957
1958 ret = SetEvent(ctx->finished);
1959 ok(ret, "SetEvent failed, last error %#lx.\n", GetLastError());
1960
1961 return 0;
1962}
_ACRTIMP unsigned int __cdecl _control87(unsigned int, unsigned int)
Definition: math.c:1265
GLfloat param
Definition: glext.h:5796
static unsigned long get_fpu_cw(void)
Definition: thread.c:1895
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733

Referenced by get_thread_fpu_cw().

◆ get_fpu_cw()

static unsigned long get_fpu_cw ( void  )
inlinestatic

Definition at line 1895 of file thread.c.

1896{
1897#ifdef __arm64ec__
1898 extern NTSTATUS (*__os_arm64x_get_x64_information)(ULONG,void*,void*);
1899 unsigned int cw, sse;
1900 __os_arm64x_get_x64_information( 0, &sse, NULL );
1901 __os_arm64x_get_x64_information( 2, &cw, NULL );
1902 return MAKELONG( cw, sse );
1903#elif defined(__i386__) || defined(__x86_64__)
1904 WORD cw = 0;
1905 unsigned int sse = 0;
1906#ifdef _MSC_VER
1907#if defined(__REACTOS__) && defined (__x86_64__)
1908 extern void get_fpu_cw_raw(WORD *cw, unsigned int *sse);
1909 get_fpu_cw_raw(&cw, &sse);
1910#else
1911 __asm { fnstcw [cw] }
1912 __asm { stmxcsr [sse] }
1913#endif
1914#else
1915 __asm__ volatile ("fnstcw %0" : "=m" (cw));
1916 __asm__ volatile ("stmxcsr %0" : "=m" (sse));
1917#endif
1918 return MAKELONG( cw, sse );
1919#elif defined(__aarch64__)
1920 ULONG_PTR cw;
1921 __asm__ __volatile__( "mrs %0, fpcr" : "=r" (cw) );
1922 return cw;
1923#else
1924 return 0;
1925#endif
1926}
#define NTSTATUS
Definition: precomp.h:19
unsigned short WORD
Definition: ntddk_ex.h:93
static ULONG
Definition: thread.c:81
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249

Referenced by fpu_thread(), and test_thread_fpu_cw().

◆ get_thread_fpu_cw()

static unsigned int get_thread_fpu_cw ( unsigned long fpu_cw)
static

Definition at line 1964 of file thread.c.

1965{
1966 struct fpu_thread_ctx ctx;
1967 DWORD tid, res;
1968 HANDLE thread;
1969
1970 ctx.finished = CreateEventW(NULL, FALSE, FALSE, NULL);
1971 ok(!!ctx.finished, "Failed to create event, last error %#lx.\n", GetLastError());
1972
1973 thread = CreateThread(NULL, 0, fpu_thread, &ctx, 0, &tid);
1974 ok(!!thread, "Failed to create thread, last error %#lx.\n", GetLastError());
1975
1976 res = WaitForSingleObject(ctx.finished, INFINITE);
1977 ok(res == WAIT_OBJECT_0, "Wait failed (%#lx), last error %#lx.\n", res, GetLastError());
1978
1979 res = CloseHandle(ctx.finished);
1980 ok(!!res, "Failed to close event handle, last error %#lx.\n", GetLastError());
1981
1983 *fpu_cw = ctx.fpu_cw;
1984 return ctx.cw;
1985}
static HANDLE thread
Definition: service.c:33
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
#define INFINITE
Definition: serial.h:102
GLuint res
Definition: glext.h:9613
static TfClientId tid
static DWORD WINAPI fpu_thread(void *param)
Definition: thread.c:1950
unsigned long fpu_cw
Definition: thread.c:1891
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
#define WAIT_OBJECT_0
Definition: winbase.h:383

Referenced by test_thread_fpu_cw().

◆ HANDLE()

static HANDLE ( WINAPI pOpenThread)
static

◆ HRESULT()

static HRESULT ( WINAPI pSetThreadDescription)
static

◆ init_funcs()

static void init_funcs ( void  )
static

Definition at line 2593 of file thread.c.

2594{
2595 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
2596 HMODULE ntdll = GetModuleHandleA("ntdll.dll");
2597
2598/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
2599 so that the compile passes */
2600
2601#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
2604 X(OpenThread);
2613
2620
2625
2626 X(FlsAlloc);
2627 X(FlsFree);
2628 X(FlsSetValue);
2629 X(FlsGetValue);
2630#undef X
2631
2632#define X(f) p##f = (void*)GetProcAddress(ntdll, #f)
2633 if (ntdll)
2634 {
2640 }
2641#undef X
2642}
HRESULT WINAPI DECLSPEC_HOTPATCH SetThreadDescription(HANDLE thread, PCWSTR description)
#define IsWow64Process
Definition: compat.h:760
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
BOOL WINAPI SetThreadStackGuarantee(IN OUT PULONG StackSizeInBytes)
Definition: thread.c:1006
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
BOOL WINAPI DECLSPEC_HOTPATCH GetThreadGroupAffinity(HANDLE thread, GROUP_AFFINITY *affinity)
Definition: thread.c:212
PTP_POOL WINAPI DECLSPEC_HOTPATCH CreateThreadpool(void *reserved)
Definition: thread.c:1255
void WINAPI DECLSPEC_HOTPATCH GetCurrentThreadStackLimits(ULONG_PTR *low, ULONG_PTR *high)
Definition: thread.c:131
DWORD WINAPI DECLSPEC_HOTPATCH GetThreadErrorMode(void)
Definition: thread.c:203
HRESULT WINAPI DECLSPEC_HOTPATCH GetThreadDescription(HANDLE thread, WCHAR **description)
Definition: thread.c:435
BOOL WINAPI SetThreadErrorMode(DWORD mode, DWORD *old)
Definition: thread.c:474
PTP_WORK WINAPI DECLSPEC_HOTPATCH CreateThreadpoolWork(PTP_WORK_CALLBACK callback, PVOID userdata, TP_CALLBACK_ENVIRON *environment)
Definition: thread.c:1325
BOOL WINAPI DECLSPEC_HOTPATCH SetThreadGroupAffinity(HANDLE thread, const GROUP_AFFINITY *new, GROUP_AFFINITY *old)
Definition: thread.c:498
NTSYSAPI ULONG WINAPI RtlRemoveVectoredExceptionHandler(PVOID)
NTSYSAPI DWORD WINAPI RtlGetThreadErrorMode(void)
Definition: error.c:217
NTSYSAPI PVOID WINAPI RtlAddVectoredExceptionHandler(ULONG, PVECTORED_EXCEPTION_HANDLER)
HANDLE hKernel32
Definition: locale.c:13
static HMODULE ntdll
Definition: debugger.c:59
#define X(f)
NTSTATUS NTAPI NtQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:2881
NTSTATUS NTAPI NtSetInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength)
Definition: query.c:2268
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
WINBASEAPI VOID WINAPI CloseThreadpoolWork(_Inout_ PTP_WORK pwk)
WINBASEAPI VOID WINAPI WaitForThreadpoolWorkCallbacks(_Inout_ PTP_WORK pwk, _In_ BOOL fCancelPendingCallbacks)
WINBASEAPI VOID WINAPI SubmitThreadpoolWork(_Inout_ PTP_WORK pwk)
WINBASEAPI VOID WINAPI CloseThreadpool(_Inout_ PTP_POOL ptpp)

Referenced by START_TEST().

◆ init_thread_sync_helpers()

static void init_thread_sync_helpers ( void  )
static

Definition at line 139 of file thread.c.

140{
142 ok(start_event != NULL, "CreateEvent failed\n");
144 ok(stop_event != NULL, "CreateEvent failed\n");
145 num_synced = -1;
146}
#define TRUE
Definition: types.h:120
static LONG num_synced
Definition: thread.c:137

Referenced by run_LS_tests().

◆ LS_InheritanceProc()

static DWORD WINAPI LS_InheritanceProc ( LPVOID  p)
static

Definition at line 1575 of file thread.c.

1576{
1577 /* We should NOT inherit the FLS/TLS values from our parent or from the
1578 main thread. */
1579 LPVOID val;
1580
1581 val = LS_GetValueFunc(LS_main);
1582 ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1583
1584 val = LS_GetValueFunc(LS_index0);
1585 ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1586
1587 val = LS_GetValueFunc(LS_index1);
1588 ok(val == NULL, "%s inheritance failed\n", LS_GetValueFuncName);
1589
1590 return 0;
1591}
GLuint GLfloat * val
Definition: glext.h:7180
static DWORD LS_index1
Definition: thread.c:1548
static DWORD LS_main
Definition: thread.c:1547
static DWORD LS_index0
Definition: thread.c:1548
static const char * LS_GetValueFuncName
Definition: thread.c:1559

Referenced by LS_ThreadProc().

◆ LS_ThreadProc()

static DWORD WINAPI LS_ThreadProc ( LPVOID  p)
static

Definition at line 1596 of file thread.c.

1597{
1598 LONG_PTR id = (LONG_PTR) p;
1599 LPVOID val;
1600 BOOL ret;
1601
1602 if (sync_threads_and_run_one(0, id))
1603 {
1604 LS_index0 = LS_AllocFunc();
1606 }
1608
1609 if (sync_threads_and_run_one(1, id))
1610 {
1611 LS_index1 = LS_AllocFunc();
1613
1614 /* Slot indices should be different even if created in different
1615 threads. */
1616 ok(LS_index0 != LS_index1, "%s failed\n", LS_AllocFuncName);
1617
1618 /* Both slots should be initialized to NULL */
1619 SetLastError(0xdeadbeef);
1620 val = LS_GetValueFunc(LS_index0);
1621 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1622 ok(val == NULL, "Slot not initialized correctly\n");
1623
1624 SetLastError(0xdeadbeef);
1625 val = LS_GetValueFunc(LS_index1);
1626 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1627 ok(val == NULL, "Slot not initialized correctly\n");
1628 }
1630
1631 if (sync_threads_and_run_one(0, id))
1632 {
1633 SetLastError(0xdeadbeef);
1634 val = LS_GetValueFunc(LS_index0);
1635 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1636 ok(val == NULL, "Slot not initialized correctly\n");
1637
1638 SetLastError(0xdeadbeef);
1639 val = LS_GetValueFunc(LS_index1);
1640 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1641 ok(val == NULL, "Slot not initialized correctly\n");
1642
1643 ret = LS_SetValueFunc(LS_index0, (LPVOID) 1);
1644 ok(ret, "%s failed\n", LS_SetValueFuncName);
1645
1646 ret = LS_SetValueFunc(LS_index1, (LPVOID) 2);
1647 ok(ret, "%s failed\n", LS_SetValueFuncName);
1648
1649 SetLastError(0xdeadbeef);
1650 val = LS_GetValueFunc(LS_index0);
1651 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1652 ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
1653
1654 SetLastError(0xdeadbeef);
1655 val = LS_GetValueFunc(LS_index1);
1656 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1657 ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
1658 }
1660
1661 if (sync_threads_and_run_one(1, id))
1662 {
1663 val = LS_GetValueFunc(LS_index0);
1664 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1665 ok(val == NULL, "Slot not initialized correctly\n");
1666
1667 val = LS_GetValueFunc(LS_index1);
1668 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1669 ok(val == NULL, "Slot not initialized correctly\n");
1670
1671 ret = LS_SetValueFunc(LS_index0, (LPVOID) 3);
1672 ok(ret, "%s failed\n", LS_SetValueFuncName);
1673
1674 ret = LS_SetValueFunc(LS_index1, (LPVOID) 4);
1675 ok(ret, "%s failed\n", LS_SetValueFuncName);
1676
1677 val = LS_GetValueFunc(LS_index0);
1678 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1679 ok(val == (LPVOID) 3, "Slot not initialized correctly\n");
1680
1681 val = LS_GetValueFunc(LS_index1);
1682 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1683 ok(val == (LPVOID) 4, "Slot not initialized correctly\n");
1684 }
1686
1687 if (sync_threads_and_run_one(0, id))
1688 {
1689 HANDLE thread;
1690 DWORD waitret, tid;
1691
1692 val = LS_GetValueFunc(LS_index0);
1693 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1694 ok(val == (LPVOID) 1, "Slot not initialized correctly\n");
1695
1696 val = LS_GetValueFunc(LS_index1);
1697 ok(GetLastError() == ERROR_SUCCESS, "%s failed\n", LS_GetValueFuncName);
1698 ok(val == (LPVOID) 2, "Slot not initialized correctly\n");
1699
1701 ok(thread != NULL, "CreateThread failed\n");
1702 waitret = WaitForSingleObject(thread, 60000);
1703 ok(waitret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
1705
1706 ret = LS_FreeFunc(LS_index0);
1707 ok(ret, "%s failed\n", LS_FreeFuncName);
1708 }
1710
1711 if (sync_threads_and_run_one(1, id))
1712 {
1713 ret = LS_FreeFunc(LS_index1);
1714 ok(ret, "%s failed\n", LS_FreeFuncName);
1715 }
1717
1718 return 0;
1719}
#define ERROR_SUCCESS
Definition: deptool.c:10
#define SetLastError(x)
Definition: compat.h:752
GLfloat GLfloat p
Definition: glext.h:8902
static const char * LS_SetValueFuncName
Definition: thread.c:1560
static const char * LS_AllocFuncName
Definition: thread.c:1558
static const char * LS_FreeFuncName
Definition: thread.c:1561
static DWORD WINAPI LS_InheritanceProc(LPVOID p)
Definition: thread.c:1575
static void resync_after_run(void)
Definition: thread.c:165
static BOOL sync_threads_and_run_one(DWORD sync_id, DWORD my_id)
Definition: thread.c:148
static DWORD LS_OutOfIndexesValue
Definition: thread.c:1549
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define LONG_PTR
Definition: treelist.c:79

Referenced by run_LS_tests().

◆ msvc_threadname_vec_handler()

static LONG CALLBACK msvc_threadname_vec_handler ( EXCEPTION_POINTERS ExceptionInfo)
static

Definition at line 2387 of file thread.c.

2388{
2389 if (ExceptionInfo->ExceptionRecord != NULL &&
2390 ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_WINE_NAME_THREAD)
2392
2394}
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
DWORD ExceptionCode
Definition: compat.h:208

Referenced by test_thread_description().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pNtQueryInformationThread)
static

◆ PTP_POOL()

static PTP_POOL ( WINAPI pCreateThreadpool)
static

◆ PTP_WORK()

static PTP_WORK ( WINAPI pCreateThreadpoolWork)
static

◆ PVOID()

static const WCHAR *static WCHAR **static PVOID ( WINAPI pRtlAddVectoredExceptionHandler)
static

◆ resync_after_run()

static void resync_after_run ( void  )
static

Definition at line 165 of file thread.c.

166{
168 assert(-1 <= num && num <= 1);
169 if (num == -1)
170 {
173 }
174 else
175 {
177 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
178 }
179}
#define InterlockedDecrement
Definition: armddk.h:52
#define assert(_expr)
Definition: assert.h:32
GLuint GLuint num
Definition: glext.h:9618
long LONG
Definition: pedump.c:60
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 1721 of file thread.c.

1722{
1723 HANDLE threads[2];
1724 LONG_PTR i;
1725 DWORD ret;
1726 BOOL suc;
1727
1729
1730 /* Allocate a slot in the main thread to test for inheritance. */
1731 LS_main = LS_AllocFunc();
1732 ok(LS_main != LS_OutOfIndexesValue, "%s failed\n", LS_AllocFuncName);
1733 suc = LS_SetValueFunc(LS_main, (LPVOID) 4114);
1734 ok(suc, "%s failed\n", LS_SetValueFuncName);
1735
1736 for (i = 0; i < 2; ++i)
1737 {
1738 DWORD tid;
1739
1741 ok(threads[i] != NULL, "CreateThread failed\n");
1742 }
1743
1744 ret = WaitForMultipleObjects(2, threads, TRUE, 60000);
1745 ok(ret == WAIT_OBJECT_0 || broken(ret == WAIT_OBJECT_0+1 /* nt4,w2k */), "WaitForAllObjects 2 threads %ld\n",ret);
1746
1747 for (i = 0; i < 2; ++i)
1749
1750 suc = LS_FreeFunc(LS_main);
1751 ok(suc, "%s failed\n", LS_FreeFuncName);
1753}
#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:83
static void cleanup_thread_sync_helpers(void)
Definition: thread.c:181
static DWORD WINAPI LS_ThreadProc(LPVOID p)
Definition: thread.c:1596
static void init_thread_sync_helpers(void)
Definition: thread.c:139
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 1348 of file thread.c.

1349{
1350 HANDLE event = p;
1351 SetEvent(event);
1352 ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
1353}
struct _cl_event * event
Definition: glext.h:7739

Referenced by test_RegisterWaitForSingleObject().

◆ START_TEST()

START_TEST ( thread  )

Definition at line 2644 of file thread.c.

2645{
2646 int argc;
2647 char **argv;
2649
2650 init_funcs();
2651
2652 if (argc >= 3)
2653 {
2654 if (!strcmp(argv[2], "sleep"))
2655 {
2656 HANDLE hAddrEvents[2];
2657 create_function_addr_events(hAddrEvents);
2658 SetEvent(hAddrEvents[0]);
2659 SetEvent(hAddrEvents[1]);
2660 Sleep(5000); /* spawned process runs for at most 5 seconds */
2661 return;
2662 }
2663 while (1)
2664 {
2666 DWORD tid;
2668 ok(hThread != NULL, "CreateThread failed, error %lu\n",
2669 GetLastError());
2671 "Thread did not exit in time\n");
2672 if (hThread == NULL) break;
2674 }
2675 return;
2676 }
2677
2692#ifdef __i386__
2693 test_SetThreadContext();
2694 test_GetThreadSelectorEntry();
2695 test_GetThreadContext();
2696#endif
2699 test_TLS();
2700 test_FLS();
2705
2707}
static int argc
Definition: ServiceArgs.c:12
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
static VOID test_GetThreadTimes(void)
Definition: thread.c:794
static void test_thread_actctx(void)
Definition: thread.c:2130
static VOID test_CreateThread_stack(void)
Definition: thread.c:647
static void test_threadpool(void)
Definition: thread.c:2209
static VOID test_SuspendThread(void)
Definition: thread.c:555
static void create_function_addr_events(HANDLE events[2])
Definition: thread.c:317
static VOID test_CreateThread_basic(void)
Definition: thread.c:419
static VOID test_CreateThread_suspended(void)
Definition: thread.c:516
static void test_RegisterWaitForSingleObject(void)
Definition: thread.c:1406
static void test_SetThreadStackGuarantee(void)
Definition: thread.c:1025
static VOID test_thread_processor(void)
Definition: thread.c:851
static VOID test_thread_priority(void)
Definition: thread.c:674
static VOID test_CreateRemoteThread(void)
Definition: thread.c:329
static void test_reserved_tls(void)
Definition: thread.c:2233
static void test_thread_description(void)
Definition: thread.c:2396
static VOID test_GetCurrentThreadStackLimits(void)
Definition: thread.c:1002
static DWORD WINAPI threadFunc2(LPVOID p)
Definition: thread.c:241
static void test_FLS(void)
Definition: thread.c:1772
static void test_thread_fpu_cw(void)
Definition: thread.c:1987
static VOID test_TerminateThread(void)
Definition: thread.c:610
static void init_funcs(void)
Definition: thread.c:2593
static void test_QueueUserWorkItem(void)
Definition: thread.c:1320
static void test_TLS(void)
Definition: thread.c:1755
static void test_thread_info(void)
Definition: thread.c:2270
static void test_ThreadErrorMode(void)
Definition: thread.c:1795
static VOID test_GetThreadExitCode(void)
Definition: thread.c:1080
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 148 of file thread.c.

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

Referenced by LS_ThreadProc().

◆ test_create()

static HANDLE test_create ( const char file)
static

Definition at line 2103 of file thread.c.

2104{
2106 ACTCTXW actctx;
2107 HANDLE handle;
2108
2110 memset(&actctx, 0, sizeof(ACTCTXW));
2111 actctx.cbSize = sizeof(ACTCTXW);
2112 actctx.lpSource = path;
2113
2115 ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %lu\n", GetLastError());
2116
2117 ok(actctx.cbSize == sizeof(actctx), "cbSize=%ld\n", actctx.cbSize);
2118 ok(actctx.dwFlags == 0, "dwFlags=%ld\n", actctx.dwFlags);
2119 ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
2120 ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
2121 ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
2122 ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
2123 ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
2124 ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
2125 ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
2126
2127 return handle;
2128}
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:102
#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 329 of file thread.c.

330{
331 HANDLE hProcess, hThread, hEvent, hRemoteEvent;
332 DWORD tid, ret, exitcode;
333 HANDLE hAddrEvents[2];
334
336 ok(hProcess != NULL, "Can't start process\n");
337
338 /* ensure threadFunc_SetEvent & threadFunc_CloseHandle are the same
339 * address as in the child process */
340 create_function_addr_events(hAddrEvents);
341 ret = WaitForMultipleObjects(2, hAddrEvents, TRUE, 5000);
342 if (ret == WAIT_TIMEOUT)
343 {
344 skip("child process wasn't mapped at same address, so can't do CreateRemoteThread tests.\n");
345 return;
346 }
347 ok(ret == WAIT_OBJECT_0 || broken(ret == WAIT_OBJECT_0+1 /* nt4,w2k */), "WaitForAllObjects 2 events %ld\n", ret);
348
350 ok(hEvent != NULL, "Can't create event, err=%lu\n", GetLastError());
353 ok(ret != 0, "DuplicateHandle failed, err=%lu\n", GetLastError());
354
355 /* create suspended remote thread with entry point SetEvent() */
356 SetLastError(0xdeadbeef);
358 hRemoteEvent, CREATE_SUSPENDED, &tid);
360 {
361 win_skip("CreateRemoteThread is not implemented\n");
362 goto cleanup;
363 }
364 ok(hThread != NULL, "CreateRemoteThread failed, err=%lu\n", GetLastError());
365 ok(tid != 0, "null tid\n");
367 ok(ret == 1, "ret=%lu, err=%lu\n", ret, GetLastError());
369 ok(ret == 2, "ret=%lu, err=%lu\n", ret, GetLastError());
370
371 /* thread still suspended, so wait times out */
373 ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%lu\n", ret);
374
376 ok(ret == 1, "ret=%lu, err=%lu\n", ret, GetLastError());
377
378 /* wait that doesn't time out */
380 ok(ret == WAIT_OBJECT_0, "object not signaled, ret=%lu\n", ret);
381
382 /* wait for thread end */
384 ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%lu\n", ret);
386
387 /* create and wait for remote thread with entry point CloseHandle() */
390 hRemoteEvent, 0, &tid);
391 ok(hThread != NULL, "CreateRemoteThread failed, err=%lu\n", GetLastError());
393 ok(ret == WAIT_OBJECT_0, "waiting for thread failed, ret=%lu\n", ret);
395
396 /* create remote thread with entry point SetEvent() */
399 hRemoteEvent, 0, &tid);
400 ok(hThread != NULL, "CreateRemoteThread failed, err=%lu\n", GetLastError());
401
402 /* closed handle, so wait times out */
404 ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%lu\n", ret);
405
406 /* check that remote SetEvent() failed */
407 ret = GetExitCodeThread(hThread, &exitcode);
408 ok(ret != 0, "GetExitCodeThread failed, err=%lu\n", GetLastError());
409 if (ret) ok(exitcode == 0, "SetEvent succeeded, expected to fail\n");
411
412cleanup:
416}
#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:1534
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
#define win_skip
Definition: minitest.h:67
static HANDLE hEvent
Definition: comm.c:54
static HANDLE create_target_process(const char *arg)
Definition: thread.c:105
#define CREATE_SUSPENDED
Definition: winbase.h:182
#define DUPLICATE_SAME_ACCESS

Referenced by START_TEST().

◆ test_CreateThread_basic()

static VOID test_CreateThread_basic ( void  )
static

Definition at line 419 of file thread.c.

420{
422 DWORD threadid[NUM_THREADS],curthreadId;
423 DWORD threadmem[NUM_THREADS];
424 DWORD exitCode;
425 t1Struct tstruct[NUM_THREADS];
426 int error;
427 DWORD i,j;
428 DWORD GLE, ret;
429 DWORD tid;
430 BOOL bRet;
431
432 /* lstrlenA contains an exception handler so this makes sure exceptions work in the main thread */
433 ok( lstrlenA( (char *)0xdeadbeef ) == 0, "lstrlenA: unexpected success\n" );
434
435/* Retrieve current Thread ID for later comparisons */
436 curthreadId=GetCurrentThreadId();
437/* Allocate some local storage */
438 ok((tlsIndex=TlsAlloc())!=TLS_OUT_OF_INDEXES,"TlsAlloc failed\n");
439/* Create events for thread synchronization */
440 for(i=0;i<NUM_THREADS;i++) {
441 threadmem[i]=0;
442/* Note that it doesn't matter what type of event we choose here. This
443 test isn't trying to thoroughly test events
444*/
446 tstruct[i].threadnum=i;
447 tstruct[i].threadmem=threadmem;
448 tstruct[i].event=event;
449 }
450
451/* Test that passing arguments to threads works okay */
452 for(i=0;i<NUM_THREADS;i++) {
454 &tstruct[i],0,&threadid[i]);
455 ok(thread[i]!=NULL,"Create Thread failed\n");
456 }
457/* Test that the threads actually complete */
458 for(i=0;i<NUM_THREADS;i++) {
460 ok(error==WAIT_OBJECT_0, "Thread did not complete within timelimit\n");
461 if(error!=WAIT_OBJECT_0) {
463 }
464 ok(GetExitCodeThread(thread[i],&exitCode),"Could not retrieve ext code\n");
465 ok(exitCode==i+NUM_THREADS,"Thread returned an incorrect exit code\n");
466 }
467/* Test that each thread executed in its parent's address space
468 (it was able to change threadmem and pass that change back to its parent)
469 and that each thread id was independent). Note that we prove that the
470 threads actually execute concurrently by having them block on each other
471 in threadFunc1
472*/
473 for(i=0;i<NUM_THREADS;i++) {
474 error=0;
475 for(j=i+1;j<NUM_THREADS;j++) {
476 if (threadmem[i]==threadmem[j]) {
477 error=1;
478 }
479 }
480 ok(!error && threadmem[i]==threadid[i] && threadmem[i]!=curthreadId,
481 "Thread did not execute successfully\n");
482 ok(CloseHandle(thread[i])!=0,"CloseHandle failed\n");
483 }
484
485 SetLastError(0xCAFEF00D);
486 bRet = TlsFree(tlsIndex);
487 ok(bRet, "TlsFree failed: %08lx\n", GetLastError());
488 ok(GetLastError()==0xCAFEF00D,
489 "GetLastError: expected 0xCAFEF00D, got %08lx\n", GetLastError());
490
491 /* Test freeing an already freed TLS index */
492 SetLastError(0xCAFEF00D);
493 ok(TlsFree(tlsIndex)==0,"TlsFree succeeded\n");
495 "GetLastError: expected ERROR_INVALID_PARAMETER, got %08lx\n", GetLastError());
496
497 /* Test how passing NULL as a pointer to threadid works */
498 SetLastError(0xFACEaBAD);
500 GLE = GetLastError();
501 if (thread[0]) { /* NT */
502 ok(GLE==0xFACEaBAD, "CreateThread set last error to %ld, expected 4207848365\n", GLE);
504 ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
505 ret = GetExitCodeThread(thread[0],&exitCode);
506 ok(ret!=0, "GetExitCodeThread returned %ld (expected nonzero)\n", ret);
507 ok(exitCode==99, "threadFunc2 exited with code: %ld (expected 99)\n", exitCode);
508 ok(CloseHandle(thread[0])!=0,"Error closing thread handle\n");
509 }
510 else { /* 9x */
511 ok(GLE==ERROR_INVALID_PARAMETER, "CreateThread set last error to %ld, expected 87\n", GLE);
512 }
513}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
BOOL WINAPI TlsFree(IN DWORD Index)
Definition: thread.c:1166
DWORD WINAPI DECLSPEC_HOTPATCH TlsAlloc(void)
Definition: thread.c:657
BOOL WINAPI DECLSPEC_HOTPATCH TerminateThread(HANDLE handle, DWORD exit_code)
Definition: thread.c:648
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:213
#define NUM_THREADS
Definition: thread.c:44
static DWORD tlsIndex
Definition: thread.c:187
int threadnum
Definition: thread.c:190
DWORD * threadmem
Definition: thread.c:192
HANDLE * event
Definition: thread.c:191
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define TLS_OUT_OF_INDEXES
Definition: winbase.h:529

Referenced by START_TEST().

◆ test_CreateThread_stack()

static VOID test_CreateThread_stack ( void  )
static

Definition at line 647 of file thread.c.

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

Referenced by START_TEST().

◆ test_CreateThread_suspended()

static VOID test_CreateThread_suspended ( void  )
static

Definition at line 516 of file thread.c.

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

Referenced by START_TEST().

◆ test_FLS()

static void test_FLS ( void  )
static

Definition at line 1772 of file thread.c.

1773{
1774 if (!pFlsAlloc || !pFlsFree || !pFlsGetValue || !pFlsSetValue)
1775 {
1776 win_skip("Fiber Local Storage not supported\n");
1777 return;
1778 }
1779
1781
1782 LS_AllocFunc = &FLS_AllocFuncThunk;
1783 LS_GetValueFunc = pFlsGetValue;
1784 LS_SetValueFunc = pFlsSetValue;
1785 LS_FreeFunc = pFlsFree;
1786
1787 LS_AllocFuncName = "FlsAlloc";
1788 LS_GetValueFuncName = "FlsGetValue";
1789 LS_SetValueFuncName = "FlsSetValue";
1790 LS_FreeFuncName = "FlsFree";
1791
1792 run_LS_tests();
1793}
static void run_LS_tests(void)
Definition: thread.c:1721
static DWORD WINAPI FLS_AllocFuncThunk(void)
Definition: thread.c:1570
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:556

Referenced by START_TEST().

◆ test_GetCurrentThreadStackLimits()

static VOID test_GetCurrentThreadStackLimits ( void  )
static

Definition at line 1002 of file thread.c.

1003{
1004 ULONG_PTR low = 0, high = 0;
1005
1006 if (!pGetCurrentThreadStackLimits)
1007 {
1008 win_skip("GetCurrentThreadStackLimits not available.\n");
1009 return;
1010 }
1011
1012 if (0)
1013 {
1014 /* crashes on native */
1015 pGetCurrentThreadStackLimits(NULL, NULL);
1016 pGetCurrentThreadStackLimits(NULL, &high);
1017 pGetCurrentThreadStackLimits(&low, NULL);
1018 }
1019
1020 pGetCurrentThreadStackLimits(&low, &high);
1021 ok(low == (ULONG_PTR)NtCurrentTeb()->DeallocationStack, "expected %p, got %Ix\n", NtCurrentTeb()->DeallocationStack, low);
1022 ok(high == (ULONG_PTR)NtCurrentTeb()->Tib.StackBase, "expected %p, got %Ix\n", NtCurrentTeb()->Tib.StackBase, high);
1023}
#define NtCurrentTeb

Referenced by START_TEST().

◆ test_GetThreadExitCode()

static VOID test_GetThreadExitCode ( void  )
static

Definition at line 1080 of file thread.c.

1081{
1082 DWORD exitCode, threadid;
1083 DWORD GLE, ret;
1084 HANDLE thread;
1085
1086 ret = GetExitCodeThread((HANDLE)0x2bad2bad,&exitCode);
1087 ok(ret==0, "GetExitCodeThread returned non zero value: %ld\n", ret);
1088 GLE = GetLastError();
1089 ok(GLE==ERROR_INVALID_HANDLE, "GetLastError returned %ld (expected 6)\n", GLE);
1090
1091 thread = CreateThread(NULL,0,threadFunc2,NULL,0,&threadid);
1093 ok(ret==WAIT_OBJECT_0, "threadFunc2 did not exit during 100 ms\n");
1094 ret = GetExitCodeThread(thread,&exitCode);
1095 ok(ret==exitCode || ret==1,
1096 "GetExitCodeThread returned %ld (expected 1 or %ld)\n", ret, exitCode);
1097 ok(exitCode==99, "threadFunc2 exited with code %ld (expected 99)\n", exitCode);
1098 ok(CloseHandle(thread)!=0,"Error closing thread handle\n");
1099}
#define ERROR_INVALID_HANDLE
Definition: compat.h:98

Referenced by START_TEST().

◆ test_GetThreadTimes()

static VOID test_GetThreadTimes ( void  )
static

Definition at line 794 of file thread.c.

795{
796 HANDLE thread,access_thread=NULL;
797 FILETIME creationTime,exitTime,kernelTime,userTime;
798 DWORD threadId;
799 int error;
800
802 CREATE_SUSPENDED,&threadId);
803
804 ok(thread!=NULL,"Create Thread failed\n");
805/* check that access control is obeyed */
806 if (pOpenThread) {
807 access_thread=pOpenThread(THREAD_ALL_ACCESS_NT4 &
808 (~THREAD_QUERY_INFORMATION), 0,threadId);
809 ok(access_thread!=NULL,
810 "OpenThread returned an invalid handle\n");
811 }
812 ok(ResumeThread(thread)==1,"Resume thread returned an invalid value\n");
814 "ResumeThread didn't work\n");
815 creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
816 exitTime.dwLowDateTime=99; exitTime.dwHighDateTime=99;
817 kernelTime.dwLowDateTime=99; kernelTime.dwHighDateTime=99;
818 userTime.dwLowDateTime=99; userTime.dwHighDateTime=99;
819/* GetThreadTimes should set all of the parameters passed to it */
820 error=GetThreadTimes(thread,&creationTime,&exitTime,
821 &kernelTime,&userTime);
822
824 win_skip("GetThreadTimes is not implemented\n");
825 else {
826 ok(error!=0,"GetThreadTimes failed\n");
827 ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
828 "creationTime was invalid\n");
829 ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
830 "exitTime was invalid\n");
831 ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
832 "kernelTimewas invalid\n");
833 ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
834 "userTime was invalid\n");
835 ok(CloseHandle(thread)!=0,"CloseHandle failed\n");
836 if(access_thread!=NULL)
837 {
838 error=GetThreadTimes(access_thread,&creationTime,&exitTime,
839 &kernelTime,&userTime);
840 obey_ar(error==0);
841 }
842 }
843 if(access_thread!=NULL) {
844 ok(CloseHandle(access_thread)!=0,"CloseHandle Failed\n");
845 }
846}
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:41
#define obey_ar(x)
Definition: thread.c:199
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 1320 of file thread.c.

1321{
1322 INT_PTR i;
1323 DWORD wait_result;
1325
1326 /* QueueUserWorkItem not present on win9x */
1327 if (!pQueueUserWorkItem) return;
1328
1330
1331 before = GetTickCount();
1332
1333 for (i = 0; i < 100; i++)
1334 {
1335 BOOL ret = pQueueUserWorkItem(work_function, (void *)i, WT_EXECUTEDEFAULT);
1336 ok(ret, "QueueUserWorkItem failed with error %ld\n", GetLastError());
1337 }
1338
1339 wait_result = WaitForSingleObject(finish_event, 10000);
1340
1341 after = GetTickCount();
1342 trace("100 QueueUserWorkItem calls took %ldms\n", after - before);
1343 ok(wait_result == WAIT_OBJECT_0, "wait failed with error 0x%lx\n", wait_result);
1344
1345 ok(times_executed == 100, "didn't execute all of the work items\n");
1346}
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
static DWORD CALLBACK work_function(void *p)
Definition: thread.c:1311
static HANDLE finish_event
Definition: thread.c:1308
static LONG times_executed
Definition: thread.c:1309
__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:1092

Referenced by START_TEST().

◆ test_RegisterWaitForSingleObject()

static void test_RegisterWaitForSingleObject ( void  )
static

Definition at line 1406 of file thread.c.

1407{
1408 BOOL ret;
1409 HANDLE wait_handle, wait_handle2;
1410 HANDLE handle;
1412 HANDLE waitthread_trigger_event, waitthread_wait_event;
1414 struct unregister_params unregister_param;
1415 DWORD i;
1416
1417 if (!pRegisterWaitForSingleObject || !pUnregisterWait)
1418 {
1419 win_skip("RegisterWaitForSingleObject or UnregisterWait not implemented\n");
1420 return;
1421 }
1422
1423 /* test signaled case */
1424
1427
1429 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1430
1432 /* give worker thread chance to complete */
1433 Sleep(100);
1434
1435 ret = pUnregisterWait(wait_handle);
1436 ok(ret, "UnregisterWait failed with error %ld\n", GetLastError());
1437
1438 /* test cancel case */
1439
1441
1443 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1444
1445 ret = pUnregisterWait(wait_handle);
1446 ok(ret, "UnregisterWait failed with error %ld\n", GetLastError());
1447
1448 /* test unregister while running */
1449
1452 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1453
1454 /* give worker thread chance to start */
1455 Sleep(50);
1456 ret = pUnregisterWait(wait_handle);
1457 ok(!ret, "UnregisterWait succeeded\n");
1458 ok(GetLastError() == ERROR_IO_PENDING, "UnregisterWait failed with error %ld\n", GetLastError());
1459
1460 /* give worker thread chance to complete */
1462 Sleep(50);
1463
1464 /* test timeout case */
1465
1467
1468 ret = pRegisterWaitForSingleObject(&wait_handle, handle, timeout_function, complete_event, 0, WT_EXECUTEONLYONCE);
1469 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1470
1472 /* give worker thread chance to complete */
1473 Sleep(100);
1474
1475 ret = pUnregisterWait(wait_handle);
1476 ok(ret, "UnregisterWait failed with error %ld\n", GetLastError());
1477
1478 SetLastError(0xdeadbeef);
1479 ret = pUnregisterWait(NULL);
1480 ok(!ret, "Expected UnregisterWait to fail\n");
1482 "Expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
1483
1484 /* test WT_EXECUTEINWAITTHREAD */
1485
1488 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1489
1491 /* give worker thread chance to complete */
1492 Sleep(100);
1493
1494 ret = pUnregisterWait(wait_handle);
1495 ok(ret, "UnregisterWait failed with error %ld\n", GetLastError());
1496
1497 /* the callback execution should be sequentially consistent with the wait handle return,
1498 even if the event is already set */
1499
1500 for (i = 0; i < 100; ++i)
1501 {
1503 unregister_param.complete_event = complete_event;
1504 unregister_param.wait_handle = INVALID_HANDLE_VALUE;
1505
1506 ret = pRegisterWaitForSingleObject(&unregister_param.wait_handle, handle, unregister_function, &unregister_param, INFINITE, WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD);
1507 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1508
1510 }
1511
1512 /* test multiple waits with WT_EXECUTEINWAITTHREAD.
1513 * Windows puts multiple waits on the same wait thread, and using WT_EXECUTEINWAITTHREAD causes the callbacks to run serially.
1514 */
1515
1517 waitthread_trigger_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1518 waitthread_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1519
1520 param.trigger_event = waitthread_trigger_event;
1521 param.wait_event = waitthread_wait_event;
1522 param.complete_event = complete_event;
1523
1524 ret = pRegisterWaitForSingleObject(&wait_handle2, waitthread_trigger_event, signaled_function, waitthread_wait_event,
1526 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1527
1529 ok(ret, "RegisterWaitForSingleObject failed with error %ld\n", GetLastError());
1530
1532 /* give worker thread chance to complete */
1533 Sleep(100);
1534
1535 ret = pUnregisterWait(wait_handle);
1536 ok(ret, "UnregisterWait failed with error %ld\n", GetLastError());
1537
1538 ret = pUnregisterWait(wait_handle2);
1539 ok(ret, "UnregisterWait failed with error %ld\n", GetLastError());
1540
1541 CloseHandle(waitthread_wait_event);
1542 CloseHandle(waitthread_trigger_event);
1545}
#define ERROR_IO_PENDING
Definition: dderror.h:15
static void CALLBACK wait_complete_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1355
static void CALLBACK timeout_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1364
static void CALLBACK signaled_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1348
static void CALLBACK unregister_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1395
static void CALLBACK waitthread_test_function(PVOID p, BOOLEAN TimerOrWaitFired)
Definition: thread.c:1378
static HANDLE complete_event
Definition: url.c:179
HANDLE wait_handle
Definition: thread.c:1391
#define WT_EXECUTEONLYONCE
Definition: winnt_old.h:1096
#define WT_EXECUTEINWAITTHREAD
Definition: winnt_old.h:1095

Referenced by START_TEST().

◆ test_reserved_tls()

static void test_reserved_tls ( void  )
static

Definition at line 2233 of file thread.c.

2234{
2235 void *val;
2236 DWORD tls;
2237 BOOL ret;
2238
2239 /* This seems to be a WinXP SP2+ feature. */
2240 if(!pIsWow64Process) {
2241 win_skip("Skipping reserved TLS slot on too old Windows.\n");
2242 return;
2243 }
2244
2245 val = TlsGetValue(0);
2246 ok(!val, "TlsGetValue(0) = %p\n", val);
2247
2248 /* Also make sure that there is a TLS allocated. */
2249 tls = TlsAlloc();
2250 ok(tls && tls != TLS_OUT_OF_INDEXES, "tls = %lx\n", tls);
2251 TlsSetValue(tls, (void*)1);
2252
2253 val = TlsGetValue(0);
2254 ok(!val, "TlsGetValue(0) = %p\n", val);
2255
2256 TlsFree(tls);
2257
2258 /* The following is too ugly to be run by default */
2259 if(0) {
2260 /* Set TLS index 0 value and see that this works and doesn't cause problems
2261 * for remaining tests. */
2262 ret = TlsSetValue(0, (void*)1);
2263 ok(ret, "TlsSetValue(0, 1) failed: %lu\n", GetLastError());
2264
2265 val = TlsGetValue(0);
2266 ok(val == (void*)1, "TlsGetValue(0) = %p\n", val);
2267 }
2268}
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_SetThreadStackGuarantee()

static void test_SetThreadStackGuarantee ( void  )
static

Definition at line 1025 of file thread.c.

1026{
1027 ULONG size;
1028 BOOL ret;
1029
1030 if (!pSetThreadStackGuarantee)
1031 {
1032 win_skip("SetThreadStackGuarantee not available.\n");
1033 return;
1034 }
1035 size = 0;
1036 ret = pSetThreadStackGuarantee( &size );
1037 ok( ret, "failed err %lu\n", GetLastError() );
1038 ok( size == 0, "wrong size %lu\n", size );
1039 ok( NtCurrentTeb()->GuaranteedStackBytes == 0, "wrong teb %lu\n",
1040 NtCurrentTeb()->GuaranteedStackBytes );
1041 size = 0xdeadbef;
1042 ret = pSetThreadStackGuarantee( &size );
1043 ok( !ret, "succeeded\n" );
1045 "wrong error %lu\n", GetLastError());
1046 ok( size == 0, "wrong size %lu\n", size );
1047 ok( NtCurrentTeb()->GuaranteedStackBytes == 0, "wrong teb %lu\n",
1048 NtCurrentTeb()->GuaranteedStackBytes );
1049 size = 200;
1050 ret = pSetThreadStackGuarantee( &size );
1051 ok( ret, "failed err %lu\n", GetLastError() );
1052 ok( size == 0, "wrong size %lu\n", size );
1053 ok( NtCurrentTeb()->GuaranteedStackBytes == 4096 * sizeof(void *) / 4, "wrong teb %lu\n",
1054 NtCurrentTeb()->GuaranteedStackBytes );
1055 size = 5000;
1056 ret = pSetThreadStackGuarantee( &size );
1057 ok( ret, "failed err %lu\n", GetLastError() );
1058 ok( size == 4096 * sizeof(void *) / 4, "wrong size %lu\n", size );
1059 ok( NtCurrentTeb()->GuaranteedStackBytes == 8192, "wrong teb %lu\n",
1060 NtCurrentTeb()->GuaranteedStackBytes );
1061 size = 2000;
1062 ret = pSetThreadStackGuarantee( &size );
1063 ok( ret, "failed err %lu\n", GetLastError() );
1064 ok( size == 8192, "wrong size %lu\n", size );
1065 ok( NtCurrentTeb()->GuaranteedStackBytes == 8192, "wrong teb %lu\n",
1066 NtCurrentTeb()->GuaranteedStackBytes );
1067 size = 10000;
1068 ret = pSetThreadStackGuarantee( &size );
1069 ok( ret, "failed err %lu\n", GetLastError() );
1070 ok( size == 8192, "wrong size %lu\n", size );
1071 ok( NtCurrentTeb()->GuaranteedStackBytes == 12288, "wrong teb %lu\n",
1072 NtCurrentTeb()->GuaranteedStackBytes );
1073 ret = pSetThreadStackGuarantee( &size );
1074 ok( ret, "failed err %lu\n", GetLastError() );
1075 ok( size == 12288, "wrong size %lu\n", size );
1076 ok( NtCurrentTeb()->GuaranteedStackBytes == 12288, "wrong teb %lu\n",
1077 NtCurrentTeb()->GuaranteedStackBytes );
1078}
#define ERROR_INVALID_ADDRESS
Definition: compat.h:106
uint32_t ULONG
Definition: typedefs.h:59

Referenced by START_TEST().

◆ test_SuspendThread()

static VOID test_SuspendThread ( void  )
static

Definition at line 555 of file thread.c.

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

Referenced by START_TEST().

◆ test_TerminateThread()

static VOID test_TerminateThread ( void  )
static

Definition at line 610 of file thread.c.

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

Referenced by START_TEST().

◆ test_thread_actctx()

static void test_thread_actctx ( void  )
static

Definition at line 2130 of file thread.c.

2131{
2135 DWORD tid, ret;
2136 BOOL b;
2137
2138 create_manifest_file("testdep1.manifest", manifest_dep);
2139 create_manifest_file("main.manifest", manifest_main);
2140
2141 context = test_create("main.manifest");
2142 DeleteFileA("testdep1.manifest");
2143 DeleteFileA("main.manifest");
2144
2145 handle = (void*)0xdeadbeef;
2147 ok(b, "GetCurrentActCtx failed: %lu\n", GetLastError());
2148 ok(handle == 0, "active context %p\n", handle);
2149
2150 /* without active context */
2151 param.thread_context = (void*)0xdeadbeef;
2152 param.handle = NULL;
2154 ok(thread != NULL, "failed, got %lu\n", GetLastError());
2155
2157 ok(ret == WAIT_OBJECT_0, "wait timeout\n");
2158 ok(param.thread_context == NULL, "got wrong thread context %p\n", param.thread_context);
2160
2162 ok(b, "activation failed: %lu\n", GetLastError());
2163
2164 handle = 0;
2166 ok(b, "GetCurrentActCtx failed: %lu\n", GetLastError());
2167 ok(handle != 0, "no active context\n");
2169
2170 param.handle = NULL;
2171 b = GetCurrentActCtx(&param.handle);
2172 ok(b && param.handle != NULL, "failed to get context, %lu\n", GetLastError());
2173
2174 param.thread_context = (void*)0xdeadbeef;
2176 ok(thread != NULL, "failed, got %lu\n", GetLastError());
2177
2179 ok(ret == WAIT_OBJECT_0, "wait timeout\n");
2180 ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
2181 ReleaseActCtx(param.thread_context);
2183
2184 /* similar test for CreateRemoteThread() */
2185 param.thread_context = (void*)0xdeadbeef;
2187 ok(thread != NULL, "failed, got %lu\n", GetLastError());
2188
2190 ok(ret == WAIT_OBJECT_0, "wait timeout\n");
2191 ok(param.thread_context == context, "got wrong thread context %p, %p\n", param.thread_context, context);
2192 ReleaseActCtx(param.thread_context);
2194
2195 ReleaseActCtx(param.handle);
2196
2198 ok(b, "DeactivateActCtx failed: %lu\n", GetLastError());
2200}
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
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define b
Definition: ke_i.h:79
static void test_create(void)
Definition: monthcal.c:1595
static const char manifest_dep[]
Definition: thread.c:2074
static void create_manifest_file(const char *filename, const char *manifest)
Definition: thread.c:2090
static DWORD WINAPI thread_actctx_func(void *p)
Definition: thread.c:302
static const char manifest_main[]
Definition: thread.c:2080
Definition: http.c:7252
Definition: cookie.c:34

Referenced by START_TEST().

◆ test_thread_description()

static void test_thread_description ( void  )
static

Definition at line 2396 of file thread.c.

2397{
2398 THREAD_NAME_INFORMATION *thread_desc;
2399 static const WCHAR *desc = L"thread_desc";
2400 ULONG len, len2, desc_len;
2402 char buff[128];
2403 WCHAR *ptr;
2404 HRESULT hr;
2405 HANDLE thread;
2406 PVOID vectored_handler;
2408
2409 if (!pGetThreadDescription)
2410 {
2411 win_skip("Thread description API is not supported.\n");
2412 return;
2413 }
2414
2415 desc_len = lstrlenW(desc) * sizeof(*desc);
2416 thread_desc = (THREAD_NAME_INFORMATION *)buff;
2417
2418 /* Initial description. */
2419 ptr = NULL;
2420 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2421 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2422 ok(!lstrcmpW(ptr, L""), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2423 LocalFree(ptr);
2424
2425 len = 0;
2426 status = pNtQueryInformationThread(GetCurrentThread(), ThreadNameInformation, NULL, 0, &len);
2427 ok(status == STATUS_BUFFER_TOO_SMALL, "Unexpected status %#lx.\n", status);
2428 ok(len == sizeof(*thread_desc), "Unexpected structure length %lu.\n", len);
2429
2430 len2 = 0;
2431 thread_desc->ThreadName.Length = 1;
2432 thread_desc->ThreadName.MaximumLength = 0;
2433 thread_desc->ThreadName.Buffer = (WCHAR *)thread_desc;
2434 status = pNtQueryInformationThread(GetCurrentThread(), ThreadNameInformation, thread_desc, len, &len2);
2435 ok(!status, "Failed to get thread info, status %#lx.\n", status);
2436 ok(len2 == sizeof(*thread_desc), "Unexpected structure length %lu.\n", len);
2437 ok(!thread_desc->ThreadName.Length, "Unexpected description length %#x.\n", thread_desc->ThreadName.Length);
2438 ok(thread_desc->ThreadName.Buffer == (WCHAR *)(thread_desc + 1),
2439 "Unexpected description string pointer %p, %p.\n", thread_desc->ThreadName.Buffer, thread_desc);
2440
2441 hr = pSetThreadDescription(GetCurrentThread(), NULL);
2442 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#lx.\n", hr);
2443
2444 hr = pSetThreadDescription(GetCurrentThread(), desc);
2445 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#lx.\n", hr);
2446
2447 ptr = NULL;
2448 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2449 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2450 ok(!lstrcmpW(ptr, desc), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2451 LocalFree(ptr);
2452
2453 len = 0;
2454 status = pNtQueryInformationThread(GetCurrentThread(), ThreadNameInformation, NULL, 0, &len);
2455 ok(status == STATUS_BUFFER_TOO_SMALL, "Failed to get thread info, status %#lx.\n", status);
2456 ok(len == sizeof(*thread_desc) + desc_len, "Unexpected structure length %lu.\n", len);
2457
2458 len = 0;
2459 status = pNtQueryInformationThread(GetCurrentThread(), ThreadNameInformation, buff, sizeof(buff), &len);
2460 ok(!status, "Failed to get thread info.\n");
2461 ok(len == sizeof(*thread_desc) + desc_len, "Unexpected structure length %lu.\n", len);
2462
2463 ok(thread_desc->ThreadName.Length == desc_len && thread_desc->ThreadName.MaximumLength == desc_len,
2464 "Unexpected description length %u.\n", thread_desc->ThreadName.Length);
2465 ok(thread_desc->ThreadName.Buffer == (WCHAR *)(thread_desc + 1),
2466 "Unexpected description string pointer %p, %p.\n", thread_desc->ThreadName.Buffer, thread_desc);
2467 ok(!memcmp(thread_desc->ThreadName.Buffer, desc, desc_len), "Unexpected description string.\n");
2468
2469 /* Partial results. */
2470 len = 0;
2471 status = pNtQueryInformationThread(GetCurrentThread(), ThreadNameInformation, NULL, 0, &len);
2472 ok(status == STATUS_BUFFER_TOO_SMALL, "Unexpected status %#lx.\n", status);
2473 ok(len == sizeof(*thread_desc) + desc_len, "Unexpected structure length %lu.\n", len);
2474
2475 status = pNtQueryInformationThread(GetCurrentThread(), ThreadNameInformation, buff, len - sizeof(WCHAR), &len);
2476 ok(status == STATUS_BUFFER_TOO_SMALL, "Unexpected status %#lx.\n", status);
2477 ok(len == sizeof(*thread_desc) + desc_len, "Unexpected structure length %lu.\n", len);
2478
2479 /* Change description. */
2480 thread_desc->ThreadName.Length = thread_desc->ThreadName.MaximumLength = 8;
2481 lstrcpyW((WCHAR *)(thread_desc + 1), L"desc");
2482
2483 status = pNtSetInformationThread(GetCurrentThread(), ThreadNameInformation, thread_desc, sizeof(*thread_desc));
2484 ok(status == STATUS_SUCCESS, "Failed to set thread description, status %#lx.\n", status);
2485
2486 ptr = NULL;
2487 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2488 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2489 ok(!lstrcmpW(ptr, L"desc"), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2490 LocalFree(ptr);
2491
2492 status = pNtSetInformationThread(GetCurrentThread(), ThreadNameInformation, thread_desc, sizeof(*thread_desc) - 1);
2493 ok(status == STATUS_INFO_LENGTH_MISMATCH, "Unexpected status %#lx.\n", status);
2494
2496 ok(status == STATUS_ACCESS_VIOLATION, "Unexpected status %#lx.\n", status);
2497
2498 thread_desc->ThreadName.Buffer = NULL;
2499 status = pNtSetInformationThread(GetCurrentThread(), ThreadNameInformation, thread_desc, sizeof(*thread_desc));
2500 ok(status == STATUS_ACCESS_VIOLATION, "Unexpected status %#lx.\n", status);
2501
2502 hr = pSetThreadDescription(GetCurrentThread(), NULL);
2503 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#lx.\n", hr);
2504
2505 ptr = NULL;
2506 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2507 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2508 ok(!lstrcmpW(ptr, L""), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2509 LocalFree(ptr);
2510
2511 /* Set with a string from RtlInitUnicodeString. */
2512 hr = pSetThreadDescription(GetCurrentThread(), L"123");
2513 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#lx.\n", hr);
2514
2515 lstrcpyW((WCHAR *)(thread_desc + 1), L"desc");
2516 RtlInitUnicodeString(&thread_desc->ThreadName, (WCHAR *)(thread_desc + 1));
2517
2518 status = pNtSetInformationThread(GetCurrentThread(), ThreadNameInformation, thread_desc, sizeof(*thread_desc));
2519 ok(status == STATUS_SUCCESS, "Failed to set thread description, status %#lx.\n", status);
2520
2521 ptr = NULL;
2522 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2523 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2524 ok(!lstrcmpW(ptr, L"desc"), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2525 LocalFree(ptr);
2526
2527 /* Set with 0 length/NULL pointer. */
2528 hr = pSetThreadDescription(GetCurrentThread(), L"123");
2529 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#lx.\n", hr);
2530
2531 memset(thread_desc, 0, sizeof(*thread_desc));
2532 status = pNtSetInformationThread(GetCurrentThread(), ThreadNameInformation, thread_desc, sizeof(*thread_desc));
2533 ok(!status, "Failed to set thread description, status %#lx.\n", status);
2534
2535 ptr = NULL;
2536 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2537 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2538 ok(!lstrcmpW(ptr, L""), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2539 LocalFree(ptr);
2540
2541 /* Get with only THREAD_QUERY_LIMITED_INFORMATION access. */
2543
2544 ptr = NULL;
2545 hr = pGetThreadDescription(thread, &ptr);
2546 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2547 ok(!lstrcmpW(ptr, L""), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2548 LocalFree(ptr);
2549
2550 len = 0;
2551 status = pNtQueryInformationThread(thread, ThreadNameInformation, NULL, 0, &len);
2552 ok(status == STATUS_BUFFER_TOO_SMALL, "Unexpected status %#lx.\n", status);
2553 ok(len == sizeof(*thread_desc), "Unexpected structure length %lu.\n", len);
2554
2556
2557 /* Set with only THREAD_SET_LIMITED_INFORMATION access. */
2559
2560 hr = pSetThreadDescription(thread, desc);
2561 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#lx.\n", hr);
2562
2563 ptr = NULL;
2564 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2565 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2566 ok(!lstrcmpW(ptr, desc), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2567 LocalFree(ptr);
2568
2570
2571 /* The old exception-based thread name method should not affect GetThreadDescription. */
2572 hr = pSetThreadDescription(GetCurrentThread(), desc);
2573 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to set thread description, hr %#lx.\n", hr);
2574
2575 vectored_handler = pRtlAddVectoredExceptionHandler(FALSE, &msvc_threadname_vec_handler);
2576 ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
2577
2578 info.dwType = 0x1000;
2579 info.szName = "123";
2580 info.dwThreadID = -1;
2581 info.dwFlags = 0;
2582 RaiseException(EXCEPTION_WINE_NAME_THREAD, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
2583
2584 pRtlRemoveVectoredExceptionHandler(vectored_handler);
2585
2586 ptr = NULL;
2587 hr = pGetThreadDescription(GetCurrentThread(), &ptr);
2588 ok(hr == HRESULT_FROM_NT(STATUS_SUCCESS), "Failed to get thread description, hr %#lx.\n", hr);
2589 ok(!lstrcmpW(ptr, desc), "Unexpected description %s.\n", wine_dbgstr_w(ptr));
2590 LocalFree(ptr);
2591}
LONG NTSTATUS
Definition: precomp.h:26
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4246
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
#define L(x)
Definition: resources.c:13
static unsigned char buff[32768]
Definition: fatten.c:17
#define STATUS_ACCESS_VIOLATION
GLenum GLsizei len
Definition: glext.h:6722
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
@ ThreadNameInformation
Definition: winternl.h:2319
#define wine_dbgstr_w
Definition: kernel32.h:34
static PVOID ptr
Definition: dispmode.c:27
#define THREAD_QUERY_LIMITED_INFORMATION
Definition: security.c:62
#define THREAD_SET_LIMITED_INFORMATION
Definition: security.c:61
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
static LONG CALLBACK msvc_threadname_vec_handler(EXCEPTION_POINTERS *ExceptionInfo)
Definition: thread.c:2387
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
HRESULT hr
Definition: shlfolder.c:183
UNICODE_STRING ThreadName
Definition: pstypes.h:1090
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: ps.c:97
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define HRESULT_FROM_NT(x)
Definition: winerror.h:216

Referenced by START_TEST().

◆ test_thread_fpu_cw()

static void test_thread_fpu_cw ( void  )
static

Definition at line 1987 of file thread.c.

1988{
1989 static const struct {
1990 unsigned int cw; unsigned long fpu_cw; unsigned long fpu_cw_broken;
1991 } expected_cw[8] =
1992 {
1993#ifdef __i386__
1994 { _MCW_EM | _PC_53, MAKELONG( 0x27f, 0x1f80 ) },
1995 { _MCW_EM | _PC_53, MAKELONG( 0x27f, 0x1f80 ) },
1996 { _EM_INEXACT | _RC_CHOP | _PC_24, MAKELONG( 0xc60, 0x7000 ), MAKELONG( 0xc60, 0x1f80 ) },
1997 { _MCW_EM | _PC_53, MAKELONG( 0x27f, 0x1f80 ) },
1998 { _EM_INEXACT | _RC_CHOP | _PC_24, MAKELONG( 0xc60, 0x7000 ), MAKELONG( 0xc60, 0x1f80 ) },
1999 { _MCW_EM | _PC_53, MAKELONG( 0x27f, 0x1f80 ) },
2000 { _MCW_EM | _PC_53, MAKELONG( 0x27f, 0x1f81 ) },
2001 { _MCW_EM | _PC_53, MAKELONG( 0x27f, 0x1f81 ) }
2002#elif defined(__x86_64__)
2003 { _MCW_EM | _PC_64, MAKELONG( 0x27f, 0x1f80 ) },
2004 { _MCW_EM | _PC_64, MAKELONG( 0x27f, 0x1f80 ) },
2005 { _EM_INEXACT | _RC_CHOP | _PC_64, MAKELONG( 0x27f, 0x7000 ) },
2006 { _MCW_EM | _PC_64, MAKELONG( 0x27f, 0x1f80 ) },
2007 { _EM_INEXACT | _RC_CHOP | _PC_64, MAKELONG( 0x27f, 0x7000 ) },
2008 { _MCW_EM | _PC_64, MAKELONG( 0x27f, 0x1f80 ) },
2009 { _MCW_EM | _PC_64, MAKELONG( 0x27f, 0x1f81 ) },
2010 { _MCW_EM | _PC_64, MAKELONG( 0x27f, 0x1f81 ) }
2011#elif defined(__aarch64__)
2012 { _MCW_EM | _PC_64, 0 },
2013 { _MCW_EM | _PC_64, 0 },
2014 { _EM_INEXACT | _RC_CHOP | _PC_64, 0xc08f00 },
2015 { _MCW_EM | _PC_64, 0 },
2016 { _EM_INEXACT | _RC_CHOP | _PC_64, 0xc08f00 },
2017 { _MCW_EM | _PC_64, 0 },
2018 { _MCW_EM | _PC_64, 0 },
2019 { _MCW_EM | _PC_64, 0 }
2020#else
2021 { 0xdeadbeef, 0xdeadbeef }
2022#endif
2023 };
2024 unsigned int initial_cw, cw;
2025 unsigned long fpu_cw;
2026
2027 fpu_cw = get_fpu_cw();
2028 initial_cw = _control87( 0, 0 );
2029 ok(initial_cw == expected_cw[0].cw, "expected %#x got %#x\n", expected_cw[0].cw, initial_cw);
2030 ok(fpu_cw == expected_cw[0].fpu_cw, "expected %#lx got %#lx\n", expected_cw[0].fpu_cw, fpu_cw);
2031
2032 cw = get_thread_fpu_cw( &fpu_cw );
2033 ok(cw == expected_cw[1].cw, "expected %#x got %#x\n", expected_cw[1].cw, cw);
2034 ok(fpu_cw == expected_cw[1].fpu_cw, "expected %#lx got %#lx\n", expected_cw[1].fpu_cw, fpu_cw);
2035
2037 cw = _control87( 0, 0 );
2038 fpu_cw = get_fpu_cw();
2039 ok(cw == expected_cw[2].cw, "expected %#x got %#x\n", expected_cw[2].cw, cw);
2040 ok(fpu_cw == expected_cw[2].fpu_cw ||
2041 broken(expected_cw[2].fpu_cw_broken && fpu_cw == expected_cw[2].fpu_cw_broken),
2042 "expected %#lx got %#lx\n", expected_cw[2].fpu_cw, fpu_cw);
2043
2044 cw = get_thread_fpu_cw( &fpu_cw );
2045 ok(cw == expected_cw[3].cw, "expected %#x got %#x\n", expected_cw[3].cw, cw);
2046 ok(fpu_cw == expected_cw[3].fpu_cw, "expected %#lx got %#lx\n", expected_cw[3].fpu_cw, fpu_cw);
2047
2048 cw = _control87( 0, 0 );
2049 fpu_cw = get_fpu_cw();
2050 ok(cw == expected_cw[4].cw, "expected %#x got %#x\n", expected_cw[4].cw, cw);
2051 ok(fpu_cw == expected_cw[4].fpu_cw ||
2052 broken(expected_cw[4].fpu_cw_broken && fpu_cw == expected_cw[4].fpu_cw_broken),
2053 "expected %#lx got %#lx\n", expected_cw[4].fpu_cw, fpu_cw);
2054
2055 _control87( initial_cw, _MCW_EM | _MCW_RC | _MCW_PC );
2056 cw = _control87( 0, 0 );
2057 fpu_cw = get_fpu_cw();
2058 ok(cw == expected_cw[5].cw, "expected %#x got %#x\n", expected_cw[5].cw, cw);
2059 ok(fpu_cw == expected_cw[5].fpu_cw, "expected %#lx got %#lx\n", expected_cw[5].fpu_cw, fpu_cw);
2060
2062 cw = _control87( 0, 0 );
2063 fpu_cw = get_fpu_cw();
2064 ok(cw == expected_cw[6].cw, "expected %#x got %#x\n", expected_cw[6].cw, cw);
2065 ok(fpu_cw == expected_cw[6].fpu_cw, "expected %#lx got %#lx\n", expected_cw[6].fpu_cw, fpu_cw);
2066
2067 cw = _control87( initial_cw, _MCW_EM | _MCW_RC | _MCW_PC );
2068 fpu_cw = get_fpu_cw();
2069 ok(cw == expected_cw[7].cw, "expected %#x got %#x\n", expected_cw[6].cw, cw);
2070 ok(fpu_cw == expected_cw[7].fpu_cw, "expected %#lx got %#lx\n", expected_cw[6].fpu_cw, fpu_cw);
2071 _clearfp();
2072}
#define _MCW_EM
Definition: float.h:64
#define _PC_64
Definition: float.h:85
#define _MCW_PC
Definition: float.h:67
#define _MCW_RC
Definition: float.h:66
#define _EM_INEXACT
Definition: float.h:76
_ACRTIMP unsigned int __cdecl _clearfp(void)
Definition: math.c:1174
#define _PC_24
Definition: float.h:83
#define _RC_CHOP
Definition: float.h:79
#define _PC_53
Definition: float.h:84
static unsigned int get_thread_fpu_cw(unsigned long *fpu_cw)
Definition: thread.c:1964
static void fpu_invalid_operation(void)
Definition: thread.c:1928

Referenced by START_TEST().

◆ test_thread_info()

static void test_thread_info ( void  )
static

Definition at line 2270 of file thread.c.

2271{
2272 char buf[4096];
2273 static const ULONG info_size[] =
2274 {
2275 sizeof(THREAD_BASIC_INFORMATION), /* ThreadBasicInformation */
2276 sizeof(KERNEL_USER_TIMES), /* ThreadTimes */
2277 sizeof(ULONG), /* ThreadPriority */
2278 sizeof(ULONG), /* ThreadBasePriority */
2279 sizeof(ULONG_PTR), /* ThreadAffinityMask */
2280 sizeof(HANDLE), /* ThreadImpersonationToken */
2281 sizeof(THREAD_DESCRIPTOR_INFORMATION), /* ThreadDescriptorTableEntry */
2282 sizeof(BOOLEAN), /* ThreadEnableAlignmentFaultFixup */
2283 0, /* ThreadEventPair_Reusable */
2284 sizeof(ULONG_PTR), /* ThreadQuerySetWin32StartAddress */
2285 sizeof(ULONG), /* ThreadZeroTlsCell */
2286 sizeof(LARGE_INTEGER), /* ThreadPerformanceCount */
2287 sizeof(ULONG), /* ThreadAmILastThread */
2288 sizeof(ULONG), /* ThreadIdealProcessor */
2289 sizeof(ULONG), /* ThreadPriorityBoost */
2290 sizeof(ULONG_PTR), /* ThreadSetTlsArrayAddress */
2291 sizeof(ULONG), /* ThreadIsIoPending */
2292 sizeof(BOOLEAN), /* ThreadHideFromDebugger */
2293 /* FIXME: Add remaining classes */
2294 };
2295 HANDLE thread;
2297
2298 if (!pOpenThread)
2299 {
2300 win_skip("OpenThread is not available on this platform\n");
2301 return;
2302 }
2303
2304 if (!pNtQueryInformationThread)
2305 {
2306 win_skip("NtQueryInformationThread is not available on this platform\n");
2307 return;
2308 }
2309
2311 if (!thread)
2312 {
2313 win_skip("THREAD_QUERY_LIMITED_INFORMATION is not supported on this platform\n");
2314 return;
2315 }
2316
2317 for (i = 0; i < ARRAY_SIZE(info_size); i++)
2318 {
2319 memset(buf, 0, sizeof(buf));
2320
2321#ifdef __i386__
2323 {
2324 CONTEXT ctx;
2325 THREAD_DESCRIPTOR_INFORMATION *tdi = (void *)buf;
2326
2327 ctx.ContextFlags = CONTEXT_SEGMENTS;
2329 tdi->Selector = ctx.SegDs;
2330 }
2331#endif
2332 ret_len = 0;
2333 status = pNtQueryInformationThread(thread, i, buf, info_size[i], &ret_len);
2334 if (status == STATUS_NOT_IMPLEMENTED) continue;
2335 if (status == STATUS_INVALID_INFO_CLASS) continue;
2336 if (status == STATUS_UNSUCCESSFUL) continue;
2337
2338 switch (i)
2339 {
2343#ifdef __REACTOS__
2344 ok(status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED && (i == 0 || i == 14)) /* WS03 */, "for info %lu expected STATUS_SUCCESS, got %08lx (ret_len %lu)\n", i, status, ret_len);
2345#else
2346 ok(status == STATUS_SUCCESS, "for info %lu expected STATUS_SUCCESS, got %08lx (ret_len %lu)\n", i, status, ret_len);
2347#endif
2348 break;
2349
2350#ifdef __i386__
2352 ok(status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED) /* testbot VM is broken */,
2353 "for info %lu expected STATUS_SUCCESS, got %08lx (ret_len %lu)\n", i, status, ret_len);
2354 break;
2355#endif
2356
2357 case ThreadTimes:
2358#ifdef __REACTOS__
2359 ok(status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_DENIED) /* WS03 */, "for info %lu expected STATUS_SUCCESS, got %08lx (ret_len %lu)\n", i, status, ret_len);
2360#else
2361 ok(status == STATUS_SUCCESS, "for info %lu expected STATUS_SUCCESS, got %08lx (ret_len %lu)\n", i, status, ret_len);
2362#endif
2363 break;
2364
2365 case ThreadIsIoPending:
2366 todo_wine
2367 ok(status == STATUS_ACCESS_DENIED, "for info %lu expected STATUS_ACCESS_DENIED, got %08lx (ret_len %lu)\n", i, status, ret_len);
2368 break;
2369
2370 default:
2371 ok(status == STATUS_ACCESS_DENIED, "for info %lu expected STATUS_ACCESS_DENIED, got %08lx (ret_len %lu)\n", i, status, ret_len);
2372 break;
2373 }
2374 }
2375
2377}
unsigned char BOOLEAN
#define ARRAY_SIZE(A)
Definition: main.h:20
#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
@ 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
#define ULONG_PTR
Definition: config.h:101
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct _THREAD_DESCRIPTOR_INFORMATION THREAD_DESCRIPTOR_INFORMATION
#define todo_wine
Definition: minitest.h:80
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:81
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1374
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
#define BOOLEAN
Definition: pedump.c:73
union _LARGE_INTEGER LARGE_INTEGER
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by START_TEST().

◆ test_thread_priority()

static VOID test_thread_priority ( void  )
static

Definition at line 674 of file thread.c.

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

Referenced by START_TEST().

◆ test_thread_processor()

static VOID test_thread_processor ( void  )
static

Definition at line 851 of file thread.c.

852{
853 HANDLE curthread,curproc;
854 DWORD_PTR processMask,systemMask,retMask;
855 SYSTEM_INFO sysInfo;
856 BOOL is_wow64, old_wow64 = FALSE;
857 DWORD ret;
858
859 if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
860
861 if (is_wow64)
862 {
863 TEB64 *teb64 = ULongToPtr(NtCurrentTeb()->GdiBatchCount);
864 if (teb64)
865 {
866 PEB64 *peb64 = ULongToPtr(teb64->Peb);
867 old_wow64 = !peb64->LdrData;
868 }
869 }
870
871 sysInfo.dwNumberOfProcessors=0;
872 GetSystemInfo(&sysInfo);
873 ok(sysInfo.dwNumberOfProcessors>0,
874 "GetSystemInfo failed to return a valid # of processors\n");
875/* Use the current Thread/process for all tests */
876 curthread=GetCurrentThread();
877 ok(curthread!=NULL,"GetCurrentThread failed\n");
878 curproc=GetCurrentProcess();
879 ok(curproc!=NULL,"GetCurrentProcess failed\n");
880/* Check the Affinity Mask functions */
881 ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
882 "GetProcessAffinityMask failed\n");
883 ok(SetThreadAffinityMask(curthread,processMask)==processMask,
884 "SetThreadAffinityMask failed\n");
885 ok(SetThreadAffinityMask(curthread,processMask+1)==0,
886 "SetThreadAffinityMask passed for an illegal processor\n");
887/* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
888 retMask = SetThreadAffinityMask(curthread,~0);
889 ok(broken(retMask==0) || retMask==processMask,
890 "SetThreadAffinityMask(thread,-1) failed to request all processors.\n");
891
892 if (retMask == processMask)
893 {
894 /* Show that the "all processors" flag is handled in ntdll */
895 DWORD_PTR mask = ~0u;
896 NTSTATUS status = pNtSetInformationThread(curthread, ThreadAffinityMask, &mask, sizeof(mask));
897 ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS in NtSetInformationThread, got %lx\n", status);
898 }
899
900 if (retMask == processMask && sizeof(ULONG_PTR) > sizeof(ULONG))
901 {
902 /* only the low 32-bits matter */
903 retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0);
904 ok(retMask == processMask, "SetThreadAffinityMask failed\n");
905 retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0 >> 3);
906 ok(retMask == processMask, "SetThreadAffinityMask failed\n");
907 }
908
909 SetLastError(0xdeadbeef);
911 ok(ret != ~0u, "Unexpected return value %lu.\n", ret);
912
913 if (is_wow64)
914 {
915 SetLastError(0xdeadbeef);
917 todo_wine_if(old_wow64)
918 ok(ret != ~0u, "Unexpected return value %lu.\n", ret);
919
920 SetLastError(0xdeadbeef);
922 ok(ret == ~0u, "Unexpected return value %lu.\n", ret);
923 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected error %ld.\n", GetLastError());
924 }
925 else
926 {
927 SetLastError(0xdeadbeef);
929#if defined(__REACTOS__) && defined(_WIN64)
930 ok(ret == ~0u || broken(ret == 0) /* x86_64 */, "Unexpected return value %lu.\n", ret);
931 ok(GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef) /* x86_64 */, "Unexpected error %ld.\n", GetLastError());
932#else
933 ok(ret == ~0u, "Unexpected return value %lu.\n", ret);
934 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected error %ld.\n", GetLastError());
935#endif
936 }
937
939 ok(ret != ~0u, "Unexpected return value %lu.\n", ret);
940
941 if (pGetThreadGroupAffinity && pSetThreadGroupAffinity)
942 {
943 GROUP_AFFINITY affinity, affinity_new;
945
946 memset(&affinity, 0, sizeof(affinity));
947 ok(pGetThreadGroupAffinity(curthread, &affinity), "GetThreadGroupAffinity failed\n");
948
949 SetLastError(0xdeadbeef);
950 ok(!pGetThreadGroupAffinity(curthread, NULL), "GetThreadGroupAffinity succeeded\n");
952 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
953 ok(affinity.Group == 0, "Expected group 0 got %u\n", affinity.Group);
954
955 memset(&affinity_new, 0, sizeof(affinity_new));
956 affinity_new.Group = 0;
957 affinity_new.Mask = affinity.Mask;
958 ok(pSetThreadGroupAffinity(curthread, &affinity_new, &affinity), "SetThreadGroupAffinity failed\n");
959 ok(affinity_new.Mask == affinity.Mask, "Expected old affinity mask %Ix, got %Ix\n",
960 affinity_new.Mask, affinity.Mask);
961
962 /* show that the "all processors" flag is not supported for SetThreadGroupAffinity */
963 if (sysInfo.dwNumberOfProcessors < 8 * sizeof(DWORD_PTR))
964 {
965 affinity_new.Group = 0;
966 affinity_new.Mask = ~(DWORD_PTR)0;
967 SetLastError(0xdeadbeef);
968 ok(!pSetThreadGroupAffinity(curthread, &affinity_new, NULL), "SetThreadGroupAffinity succeeded\n");
970 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
971 }
972
973 affinity_new.Group = 1; /* assumes that you have less than 64 logical processors */
974 affinity_new.Mask = 0x1;
975 SetLastError(0xdeadbeef);
976 ok(!pSetThreadGroupAffinity(curthread, &affinity_new, NULL), "SetThreadGroupAffinity succeeded\n");
978 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
979
980 SetLastError(0xdeadbeef);
981 ok(!pSetThreadGroupAffinity(curthread, NULL, NULL), "SetThreadGroupAffinity succeeded\n");
983 "Expected ERROR_NOACCESS, got %ld\n", GetLastError());
984
985 /* show that the access violation was detected in ntdll */
986 status = pNtSetInformationThread(curthread, ThreadGroupInformation, NULL, sizeof(affinity_new));
988 "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status);
989
990 /* restore original mask */
991 affinity_new.Group = 0;
992 affinity_new.Mask = affinity.Mask;
993 SetLastError(0xdeadbeef);
994 ok(pSetThreadGroupAffinity(curthread, &affinity_new, &affinity), "SetThreadGroupAffinity failed\n");
995 ok(affinity_new.Mask == affinity.Mask, "Expected old affinity mask %Ix, got %Ix\n",
996 affinity_new.Mask, affinity.Mask);
997 }
998 else
999 win_skip("Get/SetThreadGroupAffinity not available\n");
1000}
#define ULongToPtr(ul)
Definition: basetsd.h:86
@ ThreadGroupInformation
Definition: compat.h:965
@ ThreadAffinityMask
Definition: compat.h:939
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
DWORD WINAPI SetThreadIdealProcessor(IN HANDLE hThread, IN DWORD dwIdealProcessor)
Definition: thread.c:866
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
BOOL is_wow64
Definition: main.c:38
#define todo_wine_if(is_todo)
Definition: minitest.h:81
$USHORT Group
Definition: ntbasedef.h:673
KAFFINITY Mask
Definition: ntbasedef.h:672
ULONG64 LdrData
Definition: winternl.h:1047
DWORD dwNumberOfProcessors
Definition: winbase.h:902
ULONG64 Peb
Definition: winternl.h:1254
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define ERROR_NOACCESS
Definition: winerror.h:902

Referenced by START_TEST().

◆ test_ThreadErrorMode()

static void test_ThreadErrorMode ( void  )
static

Definition at line 1795 of file thread.c.

1796{
1797 DWORD oldmode;
1798 DWORD mode;
1799 DWORD rtlmode;
1800 BOOL ret;
1801
1802 if (!pSetThreadErrorMode || !pGetThreadErrorMode)
1803 {
1804 win_skip("SetThreadErrorMode and/or GetThreadErrorMode unavailable (added in Windows 7)\n");
1805 return;
1806 }
1807
1808 if (!pRtlGetThreadErrorMode) {
1809 win_skip("RtlGetThreadErrorMode not available\n");
1810 return;
1811 }
1812
1813 oldmode = pGetThreadErrorMode();
1814
1815 ret = pSetThreadErrorMode(0, &mode);
1816 ok(ret, "SetThreadErrorMode failed\n");
1817 ok(mode == oldmode,
1818 "SetThreadErrorMode returned old mode 0x%lx, expected 0x%lx\n",
1819 mode, oldmode);
1820 mode = pGetThreadErrorMode();
1821 ok(mode == 0, "GetThreadErrorMode returned mode 0x%lx, expected 0\n", mode);
1822 rtlmode = pRtlGetThreadErrorMode();
1823 ok(rtlmode == 0,
1824 "RtlGetThreadErrorMode returned mode 0x%lx, expected 0\n", mode);
1825
1826 ret = pSetThreadErrorMode(SEM_FAILCRITICALERRORS, &mode);
1827 ok(ret, "SetThreadErrorMode failed\n");
1828 ok(mode == 0,
1829 "SetThreadErrorMode returned old mode 0x%lx, expected 0\n", mode);
1830 mode = pGetThreadErrorMode();
1832 "GetThreadErrorMode returned mode 0x%lx, expected SEM_FAILCRITICALERRORS\n",
1833 mode);
1834 rtlmode = pRtlGetThreadErrorMode();
1835 ok(rtlmode == 0x10,
1836 "RtlGetThreadErrorMode returned mode 0x%lx, expected 0x10\n", mode);
1837
1838 ret = pSetThreadErrorMode(SEM_NOGPFAULTERRORBOX, &mode);
1839 ok(ret, "SetThreadErrorMode failed\n");
1841 "SetThreadErrorMode returned old mode 0x%lx, expected SEM_FAILCRITICALERRORS\n",
1842 mode);
1843 mode = pGetThreadErrorMode();
1845 "GetThreadErrorMode returned mode 0x%lx, expected SEM_NOGPFAULTERRORBOX\n",
1846 mode);
1847 rtlmode = pRtlGetThreadErrorMode();
1848 ok(rtlmode == 0x20,
1849 "RtlGetThreadErrorMode returned mode 0x%lx, expected 0x20\n", mode);
1850
1851 ret = pSetThreadErrorMode(SEM_NOOPENFILEERRORBOX, NULL);
1852 ok(ret, "SetThreadErrorMode failed\n");
1853 mode = pGetThreadErrorMode();
1855 "GetThreadErrorMode returned mode 0x%lx, expected SEM_NOOPENFILEERRORBOX\n",
1856 mode);
1857 rtlmode = pRtlGetThreadErrorMode();
1858 ok(rtlmode == 0x40,
1859 "RtlGetThreadErrorMode returned mode 0x%lx, expected 0x40\n", rtlmode);
1860
1861 for (mode = 1; mode; mode <<= 1)
1862 {
1863 ret = pSetThreadErrorMode(mode, NULL);
1867 {
1868 ok(ret,
1869 "SetThreadErrorMode(0x%lx,NULL) failed with error %ld\n",
1870 mode, GetLastError());
1871 }
1872 else
1873 {
1875 ok(!ret,
1876 "SetThreadErrorMode(0x%lx,NULL) succeeded, expected failure\n",
1877 mode);
1879 "SetThreadErrorMode(0x%lx,NULL) failed with %ld, "
1880 "expected ERROR_INVALID_PARAMETER\n",
1881 mode, GLE);
1882 }
1883 }
1884
1885 pSetThreadErrorMode(oldmode, NULL);
1886}
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 2209 of file thread.c.

2210{
2211 PTP_POOL pool;
2212 PTP_WORK work;
2213 int workcalled = 0;
2214
2215 if (!pCreateThreadpool) {
2216 win_skip("thread pool apis not supported.\n");
2217 return;
2218 }
2219
2220 work = pCreateThreadpoolWork(threadpool_workcallback, &workcalled, NULL);
2221 ok (work != NULL, "Error %ld in CreateThreadpoolWork\n", GetLastError());
2222 pSubmitThreadpoolWork(work);
2223 pWaitForThreadpoolWorkCallbacks(work, FALSE);
2224 pCloseThreadpoolWork(work);
2225
2226 ok (workcalled == 1, "expected work to be called once, got %d\n", workcalled);
2227
2228 pool = pCreateThreadpool(NULL);
2229 ok (pool != NULL, "CreateThreadpool failed\n");
2230 pCloseThreadpool(pool);
2231}
static void WINAPI threadpool_workcallback(PTP_CALLBACK_INSTANCE instance, void *context, PTP_WORK work)
Definition: thread.c:2202
struct _TP_WORK * PTP_WORK
Definition: winnt_old.h:4650
struct _TP_POOL * PTP_POOL
Definition: winnt_old.h:4649

Referenced by START_TEST().

◆ test_TLS()

static void test_TLS ( void  )
static

Definition at line 1755 of file thread.c.

1756{
1758
1759 LS_AllocFunc = &TlsAlloc;
1760 LS_GetValueFunc = &TlsGetValue;
1761 LS_SetValueFunc = &TlsSetValue;
1762 LS_FreeFunc = &TlsFree;
1763
1764 LS_AllocFuncName = "TlsAlloc";
1765 LS_GetValueFuncName = "TlsGetValue";
1766 LS_SetValueFuncName = "TlsSetValue";
1767 LS_FreeFuncName = "TlsFree";
1768
1769 run_LS_tests();
1770}

Referenced by START_TEST().

◆ thread_actctx_func()

static DWORD WINAPI thread_actctx_func ( void p)
static

Definition at line 302 of file thread.c.

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

Referenced by test_thread_actctx().

◆ threadFunc1()

static DWORD WINAPI threadFunc1 ( LPVOID  p)
static

Definition at line 213 of file thread.c.

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

Referenced by test_CreateThread_basic().

◆ threadFunc2()

static DWORD WINAPI threadFunc2 ( LPVOID  p)
static

Definition at line 241 of file thread.c.

242{
243 return 99;
244}

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 246 of file thread.c.

247{
251 return 99;
252}

Referenced by test_SuspendThread().

◆ threadFunc4()

static DWORD WINAPI threadFunc4 ( LPVOID  p)
static

Definition at line 254 of file thread.c.

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

Referenced by test_TerminateThread().

◆ threadFunc_CloseHandle()

static DWORD WINAPI threadFunc_CloseHandle ( LPVOID  p)
static

Definition at line 290 of file thread.c.

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

Referenced by create_function_addr_events(), and test_CreateRemoteThread().

◆ threadFunc_SetEvent()

static DWORD WINAPI threadFunc_SetEvent ( LPVOID  p)
static

Definition at line 284 of file thread.c.

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

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 2202 of file thread.c.

2202 {
2203 int *foo = (int*)context;
2204
2205 (*foo)++;
2206}

Referenced by test_threadpool().

◆ timeout_function()

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

Definition at line 1364 of file thread.c.

1365{
1366 HANDLE event = p;
1367 SetEvent(event);
1368 ok(TimerOrWaitFired, "wait should have timed out\n");
1369}

Referenced by test_RegisterWaitForSingleObject().

◆ ULONG()

static ULONG ( WINAPI pRtlRemoveVectoredExceptionHandler)
static

◆ unregister_function()

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

Definition at line 1395 of file thread.c.

1396{
1397 struct unregister_params *param = p;
1398 HANDLE wait_handle = param->wait_handle;
1399 BOOL ret;
1400 ok(wait_handle != INVALID_HANDLE_VALUE, "invalid wait handle\n");
1401 ret = pUnregisterWait(param->wait_handle);
1402 todo_wine ok(ret, "UnregisterWait failed with error %ld\n", GetLastError());
1403 SetEvent(param->complete_event);
1404}

Referenced by test_RegisterWaitForSingleObject().

◆ void()

static void ( WINAPI pGetCurrentThreadStackLimits)
static

◆ wait_complete_function()

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

Definition at line 1355 of file thread.c.

1356{
1357 HANDLE event = p;
1358 DWORD res;
1359 ok(!TimerOrWaitFired, "wait shouldn't have timed out\n");
1361 ok(res == WAIT_OBJECT_0, "WaitForSingleObject returned %lx\n", res);
1362}

Referenced by test_RegisterWaitForSingleObject().

◆ waitthread_test_function()

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

Definition at line 1378 of file thread.c.

1379{
1380 struct waitthread_test_param *param = p;
1381 DWORD ret;
1382
1383 SetEvent(param->trigger_event);
1384 ret = WaitForSingleObject(param->wait_event, 100);
1385 ok(ret == WAIT_TIMEOUT, "wait should have timed out\n");
1386 SetEvent(param->complete_event);
1387}

Referenced by test_RegisterWaitForSingleObject().

◆ work_function()

static DWORD CALLBACK work_function ( void p)
static

Definition at line 1311 of file thread.c.

1312{
1314
1315 if (executed == 100)
1317 return 0;
1318}

Referenced by test_QueueUserWorkItem().

Variable Documentation

◆ BOOL

Definition at line 80 of file thread.c.

◆ DWORD

Definition at line 80 of file thread.c.

◆ finish_event

HANDLE finish_event
static

Definition at line 1308 of file thread.c.

Referenced by test_QueueUserWorkItem(), and work_function().

◆ HANDLE

Definition at line 84 of file thread.c.

◆ LPCVOID

Definition at line 99 of file thread.c.

◆ LS_AllocFuncName

const char* LS_AllocFuncName = ""
static

Definition at line 1558 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 1561 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 1559 of file thread.c.

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

◆ LS_index0

DWORD LS_index0
static

Definition at line 1548 of file thread.c.

Referenced by LS_InheritanceProc(), and LS_ThreadProc().

◆ LS_index1

DWORD LS_index1
static

Definition at line 1548 of file thread.c.

Referenced by LS_InheritanceProc(), and LS_ThreadProc().

◆ LS_main

DWORD LS_main
static

Definition at line 1547 of file thread.c.

Referenced by LS_InheritanceProc(), and run_LS_tests().

◆ LS_OutOfIndexesValue

DWORD LS_OutOfIndexesValue
static

Definition at line 1549 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 1560 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:75

Definition at line 2074 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 2080 of file thread.c.

Referenced by test_thread_actctx().

◆ num_synced

LONG num_synced
static

Definition at line 137 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 198 of file thread.c.

◆ PBOOL

Definition at line 79 of file thread.c.

◆ PDWORD

Definition at line 87 of file thread.c.

◆ PTP_CALLBACK_ENVIRON

Definition at line 92 of file thread.c.

◆ PULONG

Definition at line 96 of file thread.c.

◆ PULONG_PTR

Definition at line 78 of file thread.c.

◆ PVECTORED_EXCEPTION_HANDLER

const WCHAR *static WCHAR **static PVECTORED_EXCEPTION_HANDLER

Definition at line 102 of file thread.c.

◆ PVOID

◆ start_event

◆ stop_event

◆ THREADINFOCLASS

Definition at line 96 of file thread.c.

◆ times_executed

LONG times_executed
static

Definition at line 1309 of file thread.c.

Referenced by test_QueueUserWorkItem(), and work_function().

◆ tlsIndex

DWORD tlsIndex
static

Definition at line 187 of file thread.c.

Referenced by test_CreateThread_basic(), and threadFunc1().

◆ ULONG

◆ WAITORTIMERCALLBACK

WAITORTIMERCALLBACK

Definition at line 84 of file thread.c.

Referenced by test_pack_WAITORTIMERCALLBACK().