Added additional tests for WaitForSingleObject and WaitForMultipleObjects.
authorArmin Novak <armin.novak@thincast.com>
Wed, 16 Jul 2014 09:58:45 +0000 (11:58 +0200)
committerArmin Novak <armin.novak@thincast.com>
Mon, 27 Oct 2014 10:23:18 +0000 (11:23 +0100)
winpr/libwinpr/synch/test/CMakeLists.txt
winpr/libwinpr/synch/test/TestSynchMultipleThreads.c [new file with mode: 0644]
winpr/libwinpr/synch/test/TestSynchThread.c

index 68b76fa..df6a8ce 100644 (file)
@@ -12,6 +12,7 @@ set(${MODULE_PREFIX}_TESTS
        TestSynchCritical.c
        TestSynchSemaphore.c
        TestSynchThread.c
+       TestSynchMultipleThreads.c
        TestSynchTimerQueue.c
        TestSynchWaitableTimer.c
        TestSynchWaitableTimerAPC.c)
diff --git a/winpr/libwinpr/synch/test/TestSynchMultipleThreads.c b/winpr/libwinpr/synch/test/TestSynchMultipleThreads.c
new file mode 100644 (file)
index 0000000..3ced1fa
--- /dev/null
@@ -0,0 +1,154 @@
+
+#include <stdlib.h>
+
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+
+static void *test_thread(void *arg)
+{
+       long timeout = random();
+       timeout %= 1000;
+       timeout += 100;
+       Sleep(timeout);
+       ExitThread(0);
+       return NULL;
+}
+
+static int start_threads(DWORD count, HANDLE *threads)
+{
+       DWORD i;
+
+       for (i=0; i<count; i++)
+       {
+               threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread,
+                                                                 NULL, 0, NULL);
+
+               if (!threads[i])
+               {
+                       printf("CreateThread [%i] failure\n", i);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+static int close_threads(DWORD count, HANDLE *threads)
+{
+       DWORD i;
+
+       for (i=0; i<count; i++)
+       {
+               if (!CloseHandle(threads[i]))
+               {
+                       printf("CloseHandle [%d] failure\n", i);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+int TestSynchMultipleThreads(int argc, char *argv[])
+{
+#define THREADS 24
+       DWORD rc = 0, ev, i;
+       HANDLE threads[THREADS];
+
+       /* WaitForAll, timeout */
+       if (start_threads(THREADS, threads))
+               return -1;
+
+       if (WaitForMultipleObjects(THREADS, threads, TRUE, 50) != WAIT_TIMEOUT)
+       {
+               printf("WaitForMultipleObjects bWaitAll, timeout 50 failed\n");
+               rc = -1;
+       }
+
+       if (WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE) != WAIT_OBJECT_0)
+       {
+               printf("WaitForMultipleObjects bWaitAll, INFINITE failed\n");
+               rc = -1;
+       }
+
+       if (close_threads(THREADS, threads))
+               return -1;
+
+       /* WaitOne, infinite */
+       if (rc)
+               return rc;
+
+       if (start_threads(THREADS, threads))
+               return -1;
+
+       ev = WaitForMultipleObjects(THREADS, threads, FALSE, INFINITE);
+
+       if ((ev < WAIT_OBJECT_0) || (ev > (WAIT_OBJECT_0 + THREADS)))
+       {
+               printf("WaitForMultipleObjects INFINITE failed\n");
+               rc = -1;
+       }
+
+       if (WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE) != WAIT_OBJECT_0)
+       {
+               printf("WaitForMultipleObjects bWaitAll, INFINITE failed\n");
+               rc = -1;
+       }
+
+       if (close_threads(THREADS, threads))
+               return -1;
+
+       if (rc)
+               return rc;
+
+       /* WaitOne, timeout */
+       if (start_threads(THREADS, threads))
+               return -1;
+
+       if (WaitForMultipleObjects(THREADS, threads, FALSE, 50) != WAIT_TIMEOUT)
+       {
+               printf("WaitForMultipleObjects timeout 50 failed\n");
+               rc = -1;
+       }
+
+       if (WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE) != WAIT_OBJECT_0)
+       {
+               printf("WaitForMultipleObjects bWaitAll, INFINITE failed\n");
+               rc = -1;
+       }
+
+       if (close_threads(THREADS, threads))
+               return -1;
+
+       /* WaitOne, timeout, multiple joins */
+       if (start_threads(THREADS, threads))
+               return -1;
+
+       for (i=0; i<THREADS; i++)
+       {
+               if (WaitForMultipleObjects(THREADS, threads, FALSE, 0) != WAIT_TIMEOUT)
+               {
+                       printf("WaitForMultipleObjects timeout 50 failed\n");
+                       rc = -1;
+               }
+       }
+
+       if (WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE) != WAIT_OBJECT_0)
+       {
+               printf("WaitForMultipleObjects bWaitAll, INFINITE failed\n");
+               rc = -1;
+       }
+
+       if (close_threads(THREADS, threads))
+               return -1;
+
+       /* Thread detach test */
+       if (start_threads(THREADS, threads))
+               return -1;
+
+       if (close_threads(THREADS, threads))
+               return -1;
+
+       return 0;
+}
index cb8e6d2..9fde1de 100644 (file)
@@ -6,18 +6,17 @@
 static void *test_thread(void *arg)
 {
        Sleep(1000);
-
        ExitThread(0);
        return NULL;
 }
 
-int TestSynchThread(int argc, charargv[])
+int TestSynchThread(int argc, char *argv[])
 {
        DWORD rc;
        HANDLE thread;
-
        thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread,
-                       NULL, 0, NULL);
+                                                 NULL, 0, NULL);
+
        if (!thread)
        {
                printf("CreateThread failure\n");
@@ -26,6 +25,7 @@ int TestSynchThread(int argc, char* argv[])
 
        /* TryJoin should now fail. */
        rc = WaitForSingleObject(thread, 0);
+
        if (WAIT_TIMEOUT != rc)
        {
                printf("Timed WaitForSingleObject on running thread failed with %d\n", rc);
@@ -34,6 +34,7 @@ int TestSynchThread(int argc, char* argv[])
 
        /* Join the thread */
        rc = WaitForSingleObject(thread, INFINITE);
+
        if (WAIT_OBJECT_0 != rc)
        {
                printf("WaitForSingleObject on thread failed with %d\n", rc);
@@ -42,13 +43,76 @@ int TestSynchThread(int argc, char* argv[])
 
        /* TimedJoin should now succeed. */
        rc = WaitForSingleObject(thread, 0);
+
        if (WAIT_OBJECT_0 != rc)
        {
                printf("Timed WaitForSingleObject on dead thread failed with %d\n", rc);
                return -5;
        }
 
-       CloseHandle(thread);
+       if (!CloseHandle(thread))
+       {
+               printf("CloseHandle failed!");
+               return -1;
+       }
+
+       thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread,
+                                                 NULL, 0, NULL);
+
+       if (!thread)
+       {
+               printf("CreateThread failure\n");
+               return -1;
+       }
+
+       /* TryJoin should now fail. */
+       rc = WaitForSingleObject(thread, 50);
+
+       if (WAIT_TIMEOUT != rc)
+       {
+               printf("Timed WaitForSingleObject on running thread failed with %d\n", rc);
+               return -3;
+       }
+
+       /* Join the thread */
+       rc = WaitForSingleObject(thread, INFINITE);
+
+       if (WAIT_OBJECT_0 != rc)
+       {
+               printf("WaitForSingleObject on thread failed with %d\n", rc);
+               return -2;
+       }
+
+       /* TimedJoin should now succeed. */
+       rc = WaitForSingleObject(thread, 0);
+
+       if (WAIT_OBJECT_0 != rc)
+       {
+               printf("Timed WaitForSingleObject on dead thread failed with %d\n", rc);
+               return -5;
+       }
+
+       if (!CloseHandle(thread))
+       {
+               printf("CloseHandle failed!");
+               return -1;
+       }
+
+       /* Thread detach test */i
+       thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread,
+                                                 NULL, 0, NULL);
+
+       if (!thread)
+       {
+               printf("CreateThread failure\n");
+               return -1;
+       }
+
+       if (!CloseHandle(thread))
+       {
+               printf("CloseHandle failed!");
+               return -1;
+       }
 
        return 0;
 }