Fix the kernel/thread tests

Francois Gouget fgouget at free.fr
Fri Nov 29 23:01:20 CST 2002


Checked on Win95, Win98, NT4, and XP.

Changelog:

 * dlls/kernel/tests/thread.c

   {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


Index: dlls/kernel/tests/thread.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/tests/thread.c,v
retrieving revision 1.7
diff -u -r1.7 thread.c
--- dlls/kernel/tests/thread.c	30 Nov 2002 01:56:57 -0000	1.7
+++ dlls/kernel/tests/thread.c	30 Nov 2002 04:46:13 -0000
@@ -48,16 +48,18 @@
     #include "wine/exception.h"
   #endif
 #endif
-typedef HANDLE (WINAPI *OPENTHREADPTR)(DWORD,BOOL,DWORD);
-OPENTHREADPTR OpenThreadPtr;
-HANDLE WINAPI OpenThreadDefault(DWORD dwDesiredAccess,
-                         BOOL bInheritHandle,
-                         DWORD dwThreadId)
-{
-  return (HANDLE)NULL;
-}
-/* define a check for whether we are running in Win2k or XP */
-#define WIN2K_PLUS(version) (version < 0x80000000 && (version & 0xFF) >= 5)
+
+typedef BOOL (WINAPI *GetThreadPriorityBoost_t)(HANDLE,PBOOL);
+static GetThreadPriorityBoost_t pGetThreadPriorityBoost=NULL;
+
+typedef HANDLE (WINAPI *OpenThread_t)(DWORD,BOOL,DWORD);
+static OpenThread_t pOpenThread=NULL;
+
+typedef DWORD (WINAPI *SetThreadIdealProcessor_t)(HANDLE,DWORD);
+static SetThreadIdealProcessor_t pSetThreadIdealProcessor=NULL;
+
+typedef BOOL (WINAPI *SetThreadPriorityBoost_t)(HANDLE,BOOL);
+static SetThreadPriorityBoost_t pSetThreadPriorityBoost=NULL;

 /* Functions not tested yet:
   AttachThreadInput
@@ -100,7 +102,7 @@
      while(tstruct->threadmem[i]==0) ;
    }
 /* Check that noone cahnged our tls memory */
-   ok((DWORD)TlsGetValue(tlsIndex)-1==tstruct->threadnum,
+   ok((int)TlsGetValue(tlsIndex)-1==tstruct->threadnum,
       "TlsGetValue failed");
    ExitThread(NUM_THREADS+tstruct->threadnum);
 }
@@ -120,7 +122,7 @@

 VOID WINAPI threadFunc4(HANDLE event)
 {
-   if(event != (HANDLE)NULL) {
+   if(event != NULL) {
      SetEvent(event);
    }
    Sleep(99000);
@@ -147,7 +149,7 @@
 #endif

 /* 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];
    DWORD threadid[NUM_THREADS],curthreadId;
@@ -155,7 +157,7 @@
    DWORD exitCode;
    t1Struct tstruct[NUM_THREADS];
    int error;
-   int i,j;
+   DWORD i,j;
 /* Retrieve current Thread ID for later comparisons */
   curthreadId=GetCurrentThreadId();
 /* Allocate some local storage */
@@ -176,7 +178,7 @@
   for(i=0;i<NUM_THREADS;i++) {
     thread[i] = Cr`eateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc1,
                              &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 */
   for(i=0;i<NUM_THREADS;i++) {
@@ -209,7 +211,7 @@
 }

 /* Check that using the CREATE_SUSPENDED flag works */
-VOID test_CreateThread_suspended(DWORD version)
+VOID test_CreateThread_suspended()
 {
   HANDLE thread;
   DWORD threadId;
@@ -217,7 +219,7 @@

   thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc2,NULL,
                         CREATE_SUSPENDED,&threadId);
-  ok(thread!=(HANDLE)NULL,"Create Thread failed.");
+  ok(thread!=NULL,"Create Thread failed.");
 /* Check that the thread is suspended */
   ok(SuspendThread(thread)==1,"Thread did not start suspended");
   ok(ResumeThread(thread)==2,"Resume thread returned an invalid value");
@@ -238,7 +240,7 @@
 }

 /* Check that SuspendThread and ResumeThread work */
-VOID test_SuspendThread(DWORD version)
+VOID test_SuspendThread()
 {
   HANDLE thread,access_thread;
   DWORD threadId,exitCode;
@@ -246,7 +248,7 @@

   thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc3,NULL,
                         0,&threadId);
-  ok(thread!=(HANDLE)NULL,"Create Thread failed.");
+  ok(thread!=NULL,"Create Thread failed.");
 /* Check that the thread is suspended */
 /* 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,
@@ -263,11 +265,11 @@
   }
   ok(error==1,"SuspendThread did not work");
 /* check that access restrictions are obeyed */
-  if(WIN2K_PLUS(version)) {
-    access_thread=OpenThreadPtr(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME),
+  if (pOpenThread) {
+    access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_SUSPEND_RESUME),
                            0,threadId);
-    ok(access_thread!=(HANDLE)NULL,"OpenThread returned an invalid handle");
-    if(access_thread!=(HANDLE)NULL) {
+    ok(access_thread!=NULL,"OpenThread returned an invalid handle");
+    if (access_thread!=NULL) {
       ok(SuspendThread(access_thread)==-1,
          "SuspendThread did not obey access restrictions");
       ok(ResumeThread(access_thread)==-1,
@@ -285,12 +287,17 @@
   if(error!=WAIT_OBJECT_0) {
     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");
 }

 /* Check that TerminateThread works properly
 */
-VOID test_TerminateThread(DWORD version)
+VOID test_TerminateThread()
 {
   HANDLE thread,access_thread,event;
   DWORD threadId,exitCode;
@@ -299,7 +307,7 @@
   event=CreateEventA(NULL,TRUE,FALSE,NULL);
   thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc4,
                         (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
    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
@@ -308,11 +316,11 @@
   ok(WaitForSingleObject(event,5000)==WAIT_OBJECT_0,
      "TerminateThread didn't work");
 /* check that access restrictions are obeyed */
-  if(WIN2K_PLUS(version)) {
-    access_thread=OpenThreadPtr(THREAD_ALL_ACCESS & (~THREAD_TERMINATE),
+  if (pOpenThread) {
+    access_thread=pOpenThread(THREAD_ALL_ACCESS & (~THREAD_TERMINATE),
                              0,threadId);
-    ok(access_thread!=(HANDLE)NULL,"OpenThread returned an invalid handle");
-    if(access_thread!=(HANDLE)NULL) {
+    ok(access_thread!=NULL,"OpenThread returned an invalid handle");
+    if (access_thread!=NULL) {
       ok(TerminateThread(access_thread,99)==0,
          "TerminateThread did not obey access restrictions");
       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed");
@@ -324,22 +332,14 @@
      "TerminateThread didn't work");
   ok(GetExitCodeThread(thread,&exitCode)!=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");
 }

 /* Check if CreateThread obeys the specified stack size.  This code does
    not work properly, and is currently disabled
 */
-VOID test_CreateThread_stack(DWORD version)
+VOID test_CreateThread_stack()
 {
 #if CHECK_STACK
 /* The only way I know of to test the stack size is to use alloca
@@ -366,7 +366,7 @@
 }

 /* Check whether setting/retreiving thread priorities works */
-VOID test_thread_priority(DWORD version)
+VOID test_thread_priority()
 {
    HANDLE curthread,access_thread;
    DWORD curthreadId,exitCode;
@@ -384,21 +384,23 @@
    ok(GetThreadPriority(curthread)==THREAD_PRIORITY_NORMAL,
       "GetThreadPriority Failed");

-   if(WIN2K_PLUS(version)) {
+   if (pOpenThread) {
 /* check that access control is obeyed */
-     access_thread=OpenThreadPtr(THREAD_ALL_ACCESS &
+     access_thread=pOpenThread(THREAD_ALL_ACCESS &
                        (~THREAD_QUERY_INFORMATION) & (~THREAD_SET_INFORMATION),
                        0,curthreadId);
-     ok(access_thread!=(HANDLE)NULL,"OpenThread returned an invalid handle");
-     if(access_thread!=(HANDLE)NULL) {
+     ok(access_thread!=NULL,"OpenThread returned an invalid handle");
+     if (access_thread!=NULL) {
        ok(SetThreadPriority(access_thread,1)==0,
           "SetThreadPriority did not obey access restrictions");
        ok(GetThreadPriority(access_thread)==THREAD_PRIORITY_ERROR_RETURN,
           "GetThreadPriority did not obey access restrictions");
-       ok(SetThreadPriorityBoost(access_thread,1)==0,
-          "SetThreadPriorityBoost did not obey access restrictions");
-       ok(GetThreadPriorityBoost(access_thread,&error)==0,
-          "GetThreadPriorityBoost did not obey access restrictions");
+       if (pSetThreadPriorityBoost)
+         ok(pSetThreadPriorityBoost(access_thread,1)==0,
+            "SetThreadPriorityBoost did not obey access restrictions");
+       if (pGetThreadPriorityBoost)
+         ok(pGetThreadPriorityBoost(access_thread,&error)==0,
+            "GetThreadPriorityBoost did not obey access restrictions");
        ok(GetExitCodeThread(access_thread,&exitCode)==0,
           "GetExitCodeThread did not obey access restrictions");
        ok(CloseHandle(access_thread),"Error Closing thread handle");
@@ -424,25 +426,24 @@
    ok(SetThreadPriority(curthread,0)!=0,"SetThreadPriority Failed");

 /* Check thread priority boost */
-/* NOTE: This only works on WinNT/2000/XP) */
-   if(version < 0x80000000) {
+   if (pGetThreadPriorityBoost && pSetThreadPriorityBoost) {
      todo_wine {
-       ok(SetThreadPriorityBoost(curthread,1)!=0,
+       ok(pSetThreadPriorityBoost(curthread,1)!=0,
           "SetThreadPriorityBoost Failed");
-       ok(GetThreadPriorityBoost(curthread,&error)!=0 && error==1,
+       ok(pGetThreadPriorityBoost(curthread,&error)!=0 && error==1,
           "GetThreadPriorityBoost Failed");
-       ok(SetThreadPriorityBoost(curthread,0)!=0,
+       ok(pSetThreadPriorityBoost(curthread,0)!=0,
           "SetThreadPriorityBoost Failed");
-       ok(GetThreadPriorityBoost(curthread,&error)!=0 && error==0,
+       ok(pGetThreadPriorityBoost(curthread,&error)!=0 && error==0,
           "GetThreadPriorityBoost Failed");
      }
    }
 }

 /* 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;
      DWORD threadId;
      int error;
@@ -450,24 +451,22 @@
      thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc2,NULL,
                            CREATE_SUSPENDED,&threadId);

-     ok(thread!=(HANDLE)NULL,"Create Thread failed.");
+     ok(thread!=NULL,"Create Thread failed.");
 /* check that access control is obeyed */
-     if(WIN2K_PLUS(version)) {
-       access_thread=OpenThreadPtr(THREAD_ALL_ACCESS &
+     if (pOpenThread) {
+       access_thread=pOpenThread(THREAD_ALL_ACCESS &
                                    (~THREAD_QUERY_INFORMATION), 0,threadId);
-       ok(access_thread!=(HANDLE)NULL,
+       ok(access_thread!=NULL,
           "OpenThread returned an invalid handle");
      }
      ok(ResumeThread(thread)==1,"Resume thread returned an invalid value");
      ok(WaitForSingleObject(thread,5000)==WAIT_OBJECT_0,
         "ResumeThread didn't work");
-     if(WIN2K_PLUS(version)) {
-       if(access_thread!=(HANDLE)NULL) {
-         error=GetThreadTimes(access_thread,&creationTime,&exitTime,
-                              &kernelTime,&userTime);
-         ok(error==0, "GetThreadTimes did not obey access restrictions");
-         ok(CloseHandle(access_thread)!=0,"CloseHandle Failed");
-       }
+     if(access_thread!=NULL) {
+       error=GetThreadTimes(access_thread,&creationTime,&exitTime,
+                            &kernelTime,&userTime);
+       ok(error==0, "GetThreadTimes did not obey access restrictions");
+       ok(CloseHandle(access_thread)!=0,"CloseHandle Failed");
      }
      creationTime.dwLowDateTime=99; creationTime.dwHighDateTime=99;
      exitTime.dwLowDateTime=99;     exitTime.dwHighDateTime=99;
@@ -476,22 +475,24 @@
 /* GetThreadTimes should set all of the parameters passed to it */
      error=GetThreadTimes(thread,&creationTime,&exitTime,
                           &kernelTime,&userTime);
-     ok(error!=0,"GetThreadTimes failed");
-     ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
-        "creationTime was invalid");
-     ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
-        "exitTime was invalid");
-     ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
-        "kernelTime was invalid");
-     ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
-        "userTime was invalid");
-     ok(CloseHandle(thread)!=0,"CloseHandle failed");
+     if (error!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
+       ok(error!=0,"GetThreadTimes failed");
+       ok(creationTime.dwLowDateTime!=99 || creationTime.dwHighDateTime!=99,
+          "creationTime was invalid");
+       ok(exitTime.dwLowDateTime!=99 || exitTime.dwHighDateTime!=99,
+          "exitTime was invalid");
+       ok(kernelTime.dwLowDateTime!=99 || kernelTime.dwHighDateTime!=99,
+          "kernelTimewas invalid");
+       ok(userTime.dwLowDateTime!=99 || userTime.dwHighDateTime!=99,
+          "userTime was invalid");
+       ok(CloseHandle(thread)!=0,"CloseHandle failed");
+     }
 }

 /* Check the processor affinity functions */
 /* 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;
    DWORD processMask,systemMask;
@@ -504,9 +505,9 @@
       "GetSystemInfo failed to return a valid # of processors");
 /* Use the current Thread/process for all tests */
    curthread=GetCurrentThread();
-   ok(curthread!=(HANDLE)NULL,"GetCurrentThread failed");
+   ok(curthread!=NULL,"GetCurrentThread failed");
    curproc=GetCurrentProcess();
-   ok(curproc!=(HANDLE)NULL,"GetCurrentProcess failed");
+   ok(curproc!=NULL,"GetCurrentProcess failed");
 /* Check the Affinity Mask functions */
    ok(GetProcessAffinityMask(curproc,&processMask,&systemMask)!=0,
       "GetProcessAffinityMask failed");
@@ -515,41 +516,44 @@
    ok(SetThreadAffinityMask(curthread,processMask+1)==0,
       "SetThreadAffinityMask passed for an illegal processor");
 /* NOTE: This only works on WinNT/2000/XP) */
-   if(version < 0x80000000) {
+   if (pSetThreadIdealProcessor) {
      todo_wine {
-       error=SetThreadIdealProcessor(curthread,0);
-       ok(error!=-1, "SetThreadIdealProcessor failed");
-       error=SetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
+       SetLastError(0);
+       error=pSetThreadIdealProcessor(curthread,0);
+       if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
+         ok(error!=-1, "SetThreadIdealProcessor failed");
+       }
      }
+     if (GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED) {
+       error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS+1);
        ok(error==-1,
           "SetThreadIdealProccesor succeeded with an illegal processor #");
-     todo_wine {
-       error=SetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
-       ok(error==0, "SetThreadIdealProccesor returned an incorrect value");
+       todo_wine {
+         error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS);
+         ok(error==0, "SetThreadIdealProccesor returned an incorrect value");
+       }
      }
    }
 }

 START_TEST(thread)
 {
-   DWORD version;
    HINSTANCE lib;
-   version=GetVersion();
 /* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
    so that the compile passes
 */
    lib=LoadLibraryA("kernel32");
-   ok(lib!=(HANDLE)NULL,"Couldn't load kernel32.dll");
-   OpenThreadPtr=(OPENTHREADPTR)GetProcAddress(lib,"OpenThread");
-   if(OpenThreadPtr==NULL) {
-      OpenThreadPtr=&OpenThreadDefault;
-   }
-   test_CreateThread_basic(version);
-   test_CreateThread_suspended(version);
-   test_SuspendThread(version);
-   test_TerminateThread(version);
-   test_CreateThread_stack(version);
-   test_thread_priority(version);
-   test_GetThreadTimes(version);
-   test_thread_processor(version);
+   ok(lib!=NULL,"Couldn't load kernel32.dll");
+   pGetThreadPriorityBoost=(GetThreadPriorityBoost_t)GetProcAddress(lib,"GetThreadPriorityBoost");
+   pOpenThread=(OpenThread_t)GetProcAddress(lib,"OpenThread");
+   pSetThreadIdealProcessor=(SetThreadIdealProcessor_t)GetProcAddress(lib,"SetThreadIdealProcessor");
+   pSetThreadPriorityBoost=(SetThreadPriorityBoost_t)GetProcAddress(lib,"SetThreadPriorityBoost");
+   test_CreateThread_basic();
+   test_CreateThread_suspended();
+   test_SuspendThread();
+   test_TerminateThread();
+   test_CreateThread_stack();
+   test_thread_priority();
+   test_GetThreadTimes();
+   test_thread_processor();
 }



-- 
Francois Gouget         fgouget at free.fr        http://fgouget.free.fr/
           If it stinks, it's chemistry. If it moves, it's biology.
                  If it does not work, It's computer science.




More information about the wine-patches mailing list