Added additional tests for WaitForSingleObject and WaitForMultipleObjects.
This commit is contained in:
parent
5122ce939a
commit
c5bb6125c1
@ -12,6 +12,7 @@ set(${MODULE_PREFIX}_TESTS
|
|||||||
TestSynchCritical.c
|
TestSynchCritical.c
|
||||||
TestSynchSemaphore.c
|
TestSynchSemaphore.c
|
||||||
TestSynchThread.c
|
TestSynchThread.c
|
||||||
|
TestSynchMultipleThreads.c
|
||||||
TestSynchTimerQueue.c
|
TestSynchTimerQueue.c
|
||||||
TestSynchWaitableTimer.c
|
TestSynchWaitableTimer.c
|
||||||
TestSynchWaitableTimerAPC.c)
|
TestSynchWaitableTimerAPC.c)
|
||||||
|
154
winpr/libwinpr/synch/test/TestSynchMultipleThreads.c
Normal file
154
winpr/libwinpr/synch/test/TestSynchMultipleThreads.c
Normal file
@ -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;
|
||||||
|
}
|
@ -6,18 +6,17 @@
|
|||||||
static void *test_thread(void *arg)
|
static void *test_thread(void *arg)
|
||||||
{
|
{
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
|
|
||||||
ExitThread(0);
|
ExitThread(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestSynchThread(int argc, char* argv[])
|
int TestSynchThread(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
DWORD rc;
|
DWORD rc;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
|
|
||||||
thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread,
|
thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)test_thread,
|
||||||
NULL, 0, NULL);
|
NULL, 0, NULL);
|
||||||
|
|
||||||
if (!thread)
|
if (!thread)
|
||||||
{
|
{
|
||||||
printf("CreateThread failure\n");
|
printf("CreateThread failure\n");
|
||||||
@ -26,6 +25,7 @@ int TestSynchThread(int argc, char* argv[])
|
|||||||
|
|
||||||
/* TryJoin should now fail. */
|
/* TryJoin should now fail. */
|
||||||
rc = WaitForSingleObject(thread, 0);
|
rc = WaitForSingleObject(thread, 0);
|
||||||
|
|
||||||
if (WAIT_TIMEOUT != rc)
|
if (WAIT_TIMEOUT != rc)
|
||||||
{
|
{
|
||||||
printf("Timed WaitForSingleObject on running thread failed with %d\n", 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 */
|
/* Join the thread */
|
||||||
rc = WaitForSingleObject(thread, INFINITE);
|
rc = WaitForSingleObject(thread, INFINITE);
|
||||||
|
|
||||||
if (WAIT_OBJECT_0 != rc)
|
if (WAIT_OBJECT_0 != rc)
|
||||||
{
|
{
|
||||||
printf("WaitForSingleObject on thread failed with %d\n", rc);
|
printf("WaitForSingleObject on thread failed with %d\n", rc);
|
||||||
@ -42,13 +43,76 @@ int TestSynchThread(int argc, char* argv[])
|
|||||||
|
|
||||||
/* TimedJoin should now succeed. */
|
/* TimedJoin should now succeed. */
|
||||||
rc = WaitForSingleObject(thread, 0);
|
rc = WaitForSingleObject(thread, 0);
|
||||||
|
|
||||||
if (WAIT_OBJECT_0 != rc)
|
if (WAIT_OBJECT_0 != rc)
|
||||||
{
|
{
|
||||||
printf("Timed WaitForSingleObject on dead thread failed with %d\n", rc);
|
printf("Timed WaitForSingleObject on dead thread failed with %d\n", rc);
|
||||||
return -5;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user