{Get,Set}ThreadPriorityBoost and SetThreadIdealProcessor are missing

on Win95 -> use GetProcAddress.
Cleanup the handling of OpenThread.
Check SuspendThread after a thread terminates (needed by Ipix).
Remove unnecessary version checks (check for
ERROR_CALL_NOT_IMPLEMENTED and similar instead).
Cleanup casts, signed/unsigned comparisons.
This commit is contained in:
Francois Gouget 2002-11-30 19:03:19 +00:00 committed by Alexandre Julliard
parent f465a8d658
commit 952407b1e0
1 changed files with 105 additions and 102 deletions

View File

@ -48,16 +48,18 @@
#include "wine/exception.h" #include "wine/exception.h"
#endif #endif
#endif #endif
typedef HANDLE (WINAPI *OPENTHREADPTR)(DWORD,BOOL,DWORD);
OPENTHREADPTR OpenThreadPtr; typedef BOOL (WINAPI *GetThreadPriorityBoost_t)(HANDLE,PBOOL);
HANDLE WINAPI OpenThreadDefault(DWORD dwDesiredAccess, static GetThreadPriorityBoost_t pGetThreadPriorityBoost=NULL;
BOOL bInheritHandle,
DWORD dwThreadId) typedef HANDLE (WINAPI *OpenThread_t)(DWORD,BOOL,DWORD);
{ static OpenThread_t pOpenThread=NULL;
return (HANDLE)NULL;
} typedef DWORD (WINAPI *SetThreadIdealProcessor_t)(HANDLE,DWORD);
/* define a check for whether we are running in Win2k or XP */ static SetThreadIdealProcessor_t pSetThreadIdealProcessor=NULL;
#define WIN2K_PLUS(version) (version < 0x80000000 && (version & 0xFF) >= 5)
typedef BOOL (WINAPI *SetThreadPriorityBoost_t)(HANDLE,BOOL);
static SetThreadPriorityBoost_t pSetThreadPriorityBoost=NULL;
/* Functions not tested yet: /* Functions not tested yet:
AttachThreadInput AttachThreadInput
@ -100,7 +102,7 @@ VOID WINAPI threadFunc1(t1Struct *tstruct)
while(tstruct->threadmem[i]==0) ; while(tstruct->threadmem[i]==0) ;
} }
/* Check that noone cahnged our tls memory */ /* Check that noone cahnged our tls memory */
ok((DWORD)TlsGetValue(tlsIndex)-1==tstruct->threadnum, ok((int)TlsGetValue(tlsIndex)-1==tstruct->threadnum,
"TlsGetValue failed"); "TlsGetValue failed");
ExitThread(NUM_THREADS+tstruct->threadnum); ExitThread(NUM_THREADS+tstruct->threadnum);
} }
@ -120,7 +122,7 @@ VOID WINAPI threadFunc3()
VOID WINAPI threadFunc4(HANDLE event) VOID WINAPI threadFunc4(HANDLE event)
{ {
if(event != (HANDLE)NULL) { if(event != NULL) {
SetEvent(event); SetEvent(event);
} }
Sleep(99000); Sleep(99000);
@ -147,7 +149,7 @@ VOID WINAPI threadFunc5(DWORD *exitCode)
#endif #endif
/* Check basic funcationality of CreateThread and Tls* functions */ /* Check basic funcationality of CreateThread and Tls* functions */
VOID test_CreateThread_basic(DWORD version) VOID test_CreateThread_basic()
{ {
HANDLE thread[NUM_THREADS],event[NUM_THREADS]; HANDLE thread[NUM_THREADS],event[NUM_THREADS];
DWORD threadid[NUM_THREADS],curthreadId; DWORD threadid[NUM_THREADS],curthreadId;
@ -155,7 +157,7 @@ VOID test_CreateThread_basic(DWORD version)
DWORD exitCode; DWORD exitCode;
t1Struct tstruct[NUM_THREADS]; t1Struct tstruct[NUM_THREADS];
int error; int error;
int i,j; DWORD i,j;
/* Retrieve current Thread ID for later comparisons */ /* Retrieve current Thread ID for later comparisons */
curthreadId=GetCurrentThreadId(); curthreadId=GetCurrentThreadId();
/* Allocate some local storage */ /* Allocate some local storage */
@ -176,7 +178,7 @@ VOID test_CreateThread_basic(DWORD version)
for(i=0;i<NUM_THREADS;i++) { for(i=0;i<NUM_THREADS;i++) {
thread[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc1, thread[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc1,
&tstruct[i],0,&threadid[i]); &tstruct[i],0,&threadid[i]);
ok(thread[i]!=(HANDLE)NULL,"Create Thread failed."); ok(thread[i]!=NULL,"Create Thread failed.");
} }
/* Test that the threads actually complete */ /* Test that the threads actually complete */
for(i=0;i<NUM_THREADS;i++) { for(i=0;i<NUM_THREADS;i++) {
@ -209,7 +211,7 @@ VOID test_CreateThread_basic(DWORD version)
} }
/* Check that using the CREATE_SUSPENDED flag works */ /* Check that using the CREATE_SUSPENDED flag works */
VOID test_CreateThread_suspended(DWORD version) VOID test_CreateThread_suspended()
{ {
HANDLE thread; HANDLE thread;
DWORD threadId; DWORD threadId;
@ -217,7 +219,7 @@ VOID test_CreateThread_suspended(DWORD version)
thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc2,NULL, thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc2,NULL,
CREATE_SUSPENDED,&threadId); CREATE_SUSPENDED,&threadId);
ok(thread!=(HANDLE)NULL,"Create Thread failed."); ok(thread!=NULL,"Create Thread failed.");
/* Check that the thread is suspended */ /* Check that the thread is suspended */
ok(SuspendThread(thread)==1,"Thread did not start suspended"); ok(SuspendThread(thread)==1,"Thread did not start suspended");
ok(ResumeThread(thread)==2,"Resume thread returned an invalid value"); ok(ResumeThread(thread)==2,"Resume thread returned an invalid value");
@ -238,7 +240,7 @@ VOID test_CreateThread_suspended(DWORD version)
} }
/* Check that SuspendThread and ResumeThread work */ /* Check that SuspendThread and ResumeThread work */
VOID test_SuspendThread(DWORD version) VOID test_SuspendThread()
{ {
HANDLE thread,access_thread; HANDLE thread,access_thread;
DWORD threadId,exitCode; DWORD threadId,exitCode;
@ -246,7 +248,7 @@ VOID test_SuspendThread(DWORD version)
thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc3,NULL, thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc3,NULL,
0,&threadId); 0,&threadId);
ok(thread!=(HANDLE)NULL,"Create Thread failed."); ok(thread!=NULL,"Create Thread failed.");
/* Check that the thread is suspended */ /* Check that the thread is suspended */
/* Note that this is a polling method, and there is a race between /* Note that this is a polling method, and there is a race between
SuspendThread being called (in the child, and the loop below timing out, SuspendThread being called (in the child, and the loop below timing out,
@ -263,11 +265,11 @@ VOID test_SuspendThread(DWORD version)
} }
ok(error==1,"SuspendThread did not work"); ok(error==1,"SuspendThread did not work");
/* check that access restrictions are obeyed */ /* check that access restrictions are obeyed */
if(WIN2K_PLUS(version)) { if (pOpenThread) {
access_thread=OpenThreadPtr(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME), access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME),
0,threadId); 0,threadId);
ok(access_thread!=(HANDLE)NULL,"OpenThread returned an invalid handle"); ok(access_thread!=NULL,"OpenThread returned an invalid handle");
if(access_thread!=(HANDLE)NULL) { if (access_thread!=NULL) {
ok(SuspendThread(access_thread)==-1, ok(SuspendThread(access_thread)==-1,
"SuspendThread did not obey access restrictions"); "SuspendThread did not obey access restrictions");
ok(ResumeThread(access_thread)==-1, ok(ResumeThread(access_thread)==-1,
@ -285,12 +287,17 @@ VOID test_SuspendThread(DWORD version)
if(error!=WAIT_OBJECT_0) { if(error!=WAIT_OBJECT_0) {
TerminateThread(thread,1); TerminateThread(thread,1);
} }
/* Trying to suspend a terminated thread should fail */
error=SuspendThread(thread);
ok(error==0xffffffff, "wrong return code: %d", error);
ok(GetLastError()==ERROR_ACCESS_DENIED || GetLastError()==ERROR_NO_MORE_ITEMS, "unexpected error code: %ld", GetLastError());
ok(CloseHandle(thread)!=0,"CloseHandle Failed"); ok(CloseHandle(thread)!=0,"CloseHandle Failed");
} }
/* Check that TerminateThread works properly /* Check that TerminateThread works properly
*/ */
VOID test_TerminateThread(DWORD version) VOID test_TerminateThread()
{ {
HANDLE thread,access_thread,event; HANDLE thread,access_thread,event;
DWORD threadId,exitCode; DWORD threadId,exitCode;
@ -299,7 +306,7 @@ VOID test_TerminateThread(DWORD version)
event=CreateEventA(NULL,TRUE,FALSE,NULL); event=CreateEventA(NULL,TRUE,FALSE,NULL);
thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc4, thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc4,
(LPVOID)event, 0,&threadId); (LPVOID)event, 0,&threadId);
ok(thread!=(HANDLE)NULL,"Create Thread failed."); ok(thread!=NULL,"Create Thread failed.");
/* Terminate thread has a race condition in Wine. If the thread is terminated /* Terminate thread has a race condition in Wine. If the thread is terminated
before it starts, it leaves a process behind. Therefore, we wait for the before it starts, it leaves a process behind. Therefore, we wait for the
thread to signal that it has started. There is no easy way to force the thread to signal that it has started. There is no easy way to force the
@ -308,11 +315,11 @@ VOID test_TerminateThread(DWORD version)
ok(WaitForSingleObject(event,5000)==WAIT_OBJECT_0, ok(WaitForSingleObject(event,5000)==WAIT_OBJECT_0,
"TerminateThread didn't work"); "TerminateThread didn't work");
/* check that access restrictions are obeyed */ /* check that access restrictions are obeyed */
if(WIN2K_PLUS(version)) { if (pOpenThread) {
access_thread=OpenThreadPtr(THREAD_ALL_ACCESS & (~THREAD_TERMINATE), access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_TERMINATE),
0,threadId); 0,threadId);
ok(access_thread!=(HANDLE)NULL,"OpenThread returned an invalid handle"); ok(access_thread!=NULL,"OpenThread returned an invalid handle");
if(access_thread!=(HANDLE)NULL) { if (access_thread!=NULL) {
ok(TerminateThread(access_thread,99)==0, ok(TerminateThread(access_thread,99)==0,
"TerminateThread did not obey access restrictions"); "TerminateThread did not obey access restrictions");
ok(CloseHandle(access_thread)!=0,"CloseHandle Failed"); ok(CloseHandle(access_thread)!=0,"CloseHandle Failed");
@ -324,22 +331,14 @@ VOID test_TerminateThread(DWORD version)
"TerminateThread didn't work"); "TerminateThread didn't work");
ok(GetExitCodeThread(thread,&exitCode)!=STILL_ACTIVE, ok(GetExitCodeThread(thread,&exitCode)!=STILL_ACTIVE,
"TerminateThread should not leave the thread 'STILL_ACTIVE'"); "TerminateThread should not leave the thread 'STILL_ACTIVE'");
if(WIN2K_PLUS(version)) {
/*NOTE: In Win2k, GetExitCodeThread does not return the value specified by
TerminateThread, even though MSDN says it should. So currently
there is no check being done for this.
*/
trace("TerminateThread returned: 0x%lx instead of 0x%x\n",exitCode,99);
} else {
ok(exitCode==99, "TerminateThread returned invalid exit code"); ok(exitCode==99, "TerminateThread returned invalid exit code");
}
ok(CloseHandle(thread)!=0,"Error Closing thread handle"); ok(CloseHandle(thread)!=0,"Error Closing thread handle");
} }
/* Check if CreateThread obeys the specified stack size. This code does /* Check if CreateThread obeys the specified stack size. This code does
not work properly, and is currently disabled not work properly, and is currently disabled
*/ */
VOID test_CreateThread_stack(DWORD version) VOID test_CreateThread_stack()
{ {
#if CHECK_STACK #if CHECK_STACK
/* The only way I know of to test the stack size is to use alloca /* The only way I know of to test the stack size is to use alloca
@ -366,7 +365,7 @@ VOID test_CreateThread_stack(DWORD version)
} }
/* Check whether setting/retreiving thread priorities works */ /* Check whether setting/retreiving thread priorities works */
VOID test_thread_priority(DWORD version) VOID test_thread_priority()
{ {
HANDLE curthread,access_thread; HANDLE curthread,access_thread;
DWORD curthreadId,exitCode; DWORD curthreadId,exitCode;
@ -384,20 +383,22 @@ VOID test_thread_priority(DWORD version)
ok(GetThreadPriority(curthread)==THREAD_PRIORITY_NORMAL, ok(GetThreadPriority(curthread)==THREAD_PRIORITY_NORMAL,
"GetThreadPriority Failed"); "GetThreadPriority Failed");
if(WIN2K_PLUS(version)) { if (pOpenThread) {
/* check that access control is obeyed */ /* check that access control is obeyed */
access_thread=OpenThreadPtr(THREAD_ALL_ACCESS & access_thread=pOpenThread(THREAD_ALL_ACCESS &
(~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION), (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
0,curthreadId); 0,curthreadId);
ok(access_thread!=(HANDLE)NULL,"OpenThread returned an invalid handle"); ok(access_thread!=NULL,"OpenThread returned an invalid handle");
if(access_thread!=(HANDLE)NULL) { if (access_thread!=NULL) {
ok(SetThreadPriority(access_thread,1)==0, ok(SetThreadPriority(access_thread,1)==0,
"SetThreadPriority did not obey access restrictions"); "SetThreadPriority did not obey access restrictions");
ok(GetThreadPriority(access_thread)==THREAD_PRIORITY_ERROR_RETURN, ok(GetThreadPriority(access_thread)==THREAD_PRIORITY_ERROR_RETURN,
"GetThreadPriority did not obey access restrictions"); "GetThreadPriority did not obey access restrictions");
ok(SetThreadPriorityBoost(access_thread,1)==0, if (pSetThreadPriorityBoost)
ok(pSetThreadPriorityBoost(access_thread,1)==0,
"SetThreadPriorityBoost did not obey access restrictions"); "SetThreadPriorityBoost did not obey access restrictions");
ok(GetThreadPriorityBoost(access_thread,&error)==0, if (pGetThreadPriorityBoost)
ok(pGetThreadPriorityBoost(access_thread,&error)==0,
"GetThreadPriorityBoost did not obey access restrictions"); "GetThreadPriorityBoost did not obey access restrictions");
ok(GetExitCodeThread(access_thread,&exitCode)==0, ok(GetExitCodeThread(access_thread,&exitCode)==0,
"GetExitCodeThread did not obey access restrictions"); "GetExitCodeThread did not obey access restrictions");
@ -424,25 +425,24 @@ VOID test_thread_priority(DWORD version)
ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed"); ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed");
/* Check thread priority boost */ /* Check thread priority boost */
/* NOTE: This only works on WinNT/2000/XP) */ if (pGetThreadPriorityBoost && pSetThreadPriorityBoost) {
if(version < 0x80000000) {
todo_wine { todo_wine {
ok(SetThreadPriorityBoost(curthread,1)!=0, ok(pSetThreadPriorityBoost(curthread,1)!=0,
"SetThreadPriorityBoost Failed"); "SetThreadPriorityBoost Failed");
ok(GetThreadPriorityBoost(curthread,&error)!=0 && error==1, ok(pGetThreadPriorityBoost(curthread,&error)!=0 && error==1,
"GetThreadPriorityBoost Failed"); "GetThreadPriorityBoost Failed");
ok(SetThreadPriorityBoost(curthread,0)!=0, ok(pSetThreadPriorityBoost(curthread,0)!=0,
"SetThreadPriorityBoost Failed"); "SetThreadPriorityBoost Failed");
ok(GetThreadPriorityBoost(curthread,&error)!=0 && error==0, ok(pGetThreadPriorityBoost(curthread,&error)!=0 && error==0,
"GetThreadPriorityBoost Failed"); "GetThreadPriorityBoost Failed");
} }
} }
} }
/* check the GetThreadTimes function */ /* check the GetThreadTimes function */
VOID test_GetThreadTimes(DWORD version) VOID test_GetThreadTimes()
{ {
HANDLE thread,access_thread=(HANDLE)NULL; HANDLE thread,access_thread=NULL;
FILETIME creationTime,exitTime,kernelTime,userTime; FILETIME creationTime,exitTime,kernelTime,userTime;
DWORD threadId; DWORD threadId;
int error; int error;
@ -450,25 +450,23 @@ VOID test_GetThreadTimes(DWORD version)
thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc2,NULL, thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc2,NULL,
CREATE_SUSPENDED,&threadId); CREATE_SUSPENDED,&threadId);
ok(thread!=(HANDLE)NULL,"Create Thread failed."); ok(thread!=NULL,"Create Thread failed.");
/* check that access control is obeyed */ /* check that access control is obeyed */
if(WIN2K_PLUS(version)) { if (pOpenThread) {
access_thread=OpenThreadPtr(THREAD_ALL_ACCESS & access_thread=pOpenThread(THREAD_ALL_ACCESS &
(~THREAD_QUERY_INFORMATION), 0,threadId); (~THREAD_QUERY_INFORMATION), 0,threadId);
ok(access_thread!=(HANDLE)NULL, ok(access_thread!=NULL,
"OpenThread returned an invalid handle"); "OpenThread returned an invalid handle");
} }
ok(ResumeThread(thread)==1,"Resume thread returned an invalid value"); ok(ResumeThread(thread)==1,"Resume thread returned an invalid value");
ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0, ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
"ResumeThread didn't work"); "ResumeThread didn't work");
if(WIN2K_PLUS(version)) { if(access_thread!=NULL) {
if(access_thread!=(HANDLE)NULL) {
error=GetThreadTimes(access_thread,&creationTime,&exitTime, error=GetThreadTimes(access_thread,&creationTime,&exitTime,
&kernelTime,&userTime); &kernelTime,&userTime);
ok(error==0, "GetThreadTimes did not obey access restrictions"); ok(error==0, "GetThreadTimes did not obey access restrictions");
ok(CloseHandle(access_thread)!=0,"CloseHandle Failed"); ok(CloseHandle(access_thread)!=0,"CloseHandle Failed");
} }
}
creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99; creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
exitTime.dwLowDateTime=99; exitTime.dwHighDateTime=99; exitTime.dwLowDateTime=99; exitTime.dwHighDateTime=99;
kernelTime.dwLowDateTime=99; kernelTime.dwHighDateTime=99; kernelTime.dwLowDateTime=99; kernelTime.dwHighDateTime=99;
@ -476,6 +474,7 @@ VOID test_GetThreadTimes(DWORD version)
/* GetThreadTimes should set all of the parameters passed to it */ /* GetThreadTimes should set all of the parameters passed to it */
error=GetThreadTimes(thread,&creationTime,&exitTime, error=GetThreadTimes(thread,&creationTime,&exitTime,
&kernelTime,&userTime); &kernelTime,&userTime);
if (error!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
ok(error!=0,"GetThreadTimes failed"); ok(error!=0,"GetThreadTimes failed");
ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99, ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
"creationTime was invalid"); "creationTime was invalid");
@ -487,11 +486,12 @@ VOID test_GetThreadTimes(DWORD version)
"userTime was invalid"); "userTime was invalid");
ok(CloseHandle(thread)!=0,"CloseHandle failed"); ok(CloseHandle(thread)!=0,"CloseHandle failed");
} }
}
/* Check the processor affinity functions */ /* Check the processor affinity functions */
/* NOTE: These functions should also be checked that they obey access control /* NOTE: These functions should also be checked that they obey access control
*/ */
VOID test_thread_processor(DWORD version) VOID test_thread_processor()
{ {
HANDLE curthread,curproc; HANDLE curthread,curproc;
DWORD processMask,systemMask; DWORD processMask,systemMask;
@ -504,9 +504,9 @@ VOID test_thread_processor(DWORD version)
"GetSystemInfo failed to return a valid # of processors"); "GetSystemInfo failed to return a valid # of processors");
/* Use the current Thread/process for all tests */ /* Use the current Thread/process for all tests */
curthread=GetCurrentThread(); curthread=GetCurrentThread();
ok(curthread!=(HANDLE)NULL,"GetCurrentThread failed"); ok(curthread!=NULL,"GetCurrentThread failed");
curproc=GetCurrentProcess(); curproc=GetCurrentProcess();
ok(curproc!=(HANDLE)NULL,"GetCurrentProcess failed"); ok(curproc!=NULL,"GetCurrentProcess failed");
/* Check the Affinity Mask functions */ /* Check the Affinity Mask functions */
ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0, ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
"GetProcessAffinityMask failed"); "GetProcessAffinityMask failed");
@ -515,41 +515,44 @@ VOID test_thread_processor(DWORD version)
ok(SetThreadAffinityMask(curthread,processMask+1)==0, ok(SetThreadAffinityMask(curthread,processMask+1)==0,
"SetThreadAffinityMask passed for an illegal processor"); "SetThreadAffinityMask passed for an illegal processor");
/* NOTE: This only works on WinNT/2000/XP) */ /* NOTE: This only works on WinNT/2000/XP) */
if(version < 0x80000000) { if (pSetThreadIdealProcessor) {
todo_wine { todo_wine {
error=SetThreadIdealProcessor(curthread,0); SetLastError(0);
error=pSetThreadIdealProcessor(curthread,0);
if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
ok(error!=-1, "SetThreadIdealProcessor failed"); ok(error!=-1, "SetThreadIdealProcessor failed");
error=SetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
} }
}
if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
ok(error==-1, ok(error==-1,
"SetThreadIdealProccesor succeeded with an illegal processor #"); "SetThreadIdealProccesor succeeded with an illegal processor #");
todo_wine { todo_wine {
error=SetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS); error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
ok(error==0, "SetThreadIdealProccesor returned an incorrect value"); ok(error==0, "SetThreadIdealProccesor returned an incorrect value");
} }
} }
} }
}
START_TEST(thread) START_TEST(thread)
{ {
DWORD version;
HINSTANCE lib; HINSTANCE lib;
version=GetVersion();
/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check /* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
so that the compile passes so that the compile passes
*/ */
lib=LoadLibraryA("kernel32"); lib=LoadLibraryA("kernel32");
ok(lib!=(HANDLE)NULL,"Couldn't load kernel32.dll"); ok(lib!=NULL,"Couldn't load kernel32.dll");
OpenThreadPtr=(OPENTHREADPTR)GetProcAddress(lib,"OpenThread"); pGetThreadPriorityBoost=(GetThreadPriorityBoost_t)GetProcAddress(lib,"GetThreadPriorityBoost");
if(OpenThreadPtr==NULL) { pOpenThread=(OpenThread_t)GetProcAddress(lib,"OpenThread");
OpenThreadPtr=&OpenThreadDefault; pSetThreadIdealProcessor=(SetThreadIdealProcessor_t)GetProcAddress(lib,"SetThreadIdealProcessor");
} pSetThreadPriorityBoost=(SetThreadPriorityBoost_t)GetProcAddress(lib,"SetThreadPriorityBoost");
test_CreateThread_basic(version); test_CreateThread_basic();
test_CreateThread_suspended(version); test_CreateThread_suspended();
test_SuspendThread(version); test_SuspendThread();
test_TerminateThread(version); test_TerminateThread();
test_CreateThread_stack(version); test_CreateThread_stack();
test_thread_priority(version); test_thread_priority();
test_GetThreadTimes(version); test_GetThreadTimes();
test_thread_processor(version); test_thread_processor();
} }