[2/5] kernel: add CreateRemoteThread remote thread conformance
tests (update 2)
Thomas Kho
tkho at ucla.edu
Fri Aug 18 03:25:35 CDT 2006
[2/5] kernel: add CreateRemoteThread remote thread conformance tests (update 2)
This conformance test was updated to create remote threads in another instance
of itself.
Thomas Kho
---
dlls/kernel/tests/thread.c | 147 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 146 insertions(+), 1 deletions(-)
diff --git a/dlls/kernel/tests/thread.c b/dlls/kernel/tests/thread.c
index 00951b3..0c97bf2 100644
--- a/dlls/kernel/tests/thread.c
+++ b/dlls/kernel/tests/thread.c
@@ -67,9 +67,14 @@ static SetThreadIdealProcessor_t pSetThr
typedef BOOL (WINAPI *SetThreadPriorityBoost_t)(HANDLE,BOOL);
static SetThreadPriorityBoost_t pSetThreadPriorityBoost=NULL;
+/* from virtual.c */
+extern HANDLE hStressTestProcess;
+extern HANDLE hStressTestQuitEvent;
+extern HANDLE create_target_process(char *arg);
+extern void mini_stress_test(LPTHREAD_START_ROUTINE worker, char *name);
+
/* Functions not tested yet:
AttachThreadInput
- CreateRemoteThread
SetThreadContext
SwitchToThread
@@ -175,6 +180,119 @@ static DWORD WINAPI threadFunc5(LPVOID p
}
#endif
+static DWORD WINAPI threadFunc_SetEvent(LPVOID p)
+{
+ SetEvent((HANDLE) p);
+ return 0;
+}
+
+static DWORD WINAPI threadFunc_CloseHandle(LPVOID p)
+{
+ CloseHandle((HANDLE) p);
+ return 0;
+}
+
+/* check CreateRemoteThread */
+static VOID test_CreateRemoteThread(void)
+{
+ HANDLE hProcess, hThread, hEvent, hRemoteEvent;
+ DWORD tid, ret, exitcode;
+
+ hProcess = create_target_process("sleep");
+ ok(hProcess != NULL, "Can't start process\n");
+
+ hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ ok(hEvent != NULL, "Can't create event, err=%lu\n", GetLastError());
+ ret = DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hRemoteEvent,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+ ok(ret != 0, "DuplicateHandle failed, err=%lu\n", GetLastError());
+
+ /* create suspended remote thread with entry point SetEvent() */
+ hThread = CreateRemoteThread(hProcess, NULL, 0, threadFunc_SetEvent,
+ hRemoteEvent, CREATE_SUSPENDED, &tid);
+ todo_wine ok(hThread != NULL, "CreateRemoteThread failed, err=%lu\n",
+ GetLastError());
+ ok(tid != 0, "null tid\n");
+ ret = SuspendThread(hThread);
+ todo_wine ok(ret == 1, "ret=%lu, err=%lu\n", ret, GetLastError());
+ ret = ResumeThread(hThread);
+ todo_wine ok(ret == 2, "ret=%lu, err=%lu\n", ret, GetLastError());
+
+ /* thread still suspended, so wait times out */
+ ret = WaitForSingleObject(hEvent, 100);
+ ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%lu\n", ret);
+
+ ret = ResumeThread(hThread);
+ todo_wine ok(ret == 1, "ret=%lu, err=%lu\n", ret, GetLastError());
+
+ /* wait that doesn't time out */
+ ret = WaitForSingleObject(hEvent, 100);
+ todo_wine ok(ret == WAIT_OBJECT_0, "object not signaled, ret=%lu\n", ret);
+
+ /* wait for thread end */
+ ret = WaitForSingleObject(hThread, 100);
+ todo_wine ok(ret == WAIT_OBJECT_0,
+ "waiting for thread failed, ret=%lu\n", ret);
+ CloseHandle(hThread);
+
+ /* create and wait for remote thread with entry point CloseHandle() */
+ hThread = CreateRemoteThread(hProcess, NULL, 0,
+ threadFunc_CloseHandle,
+ hRemoteEvent, 0, &tid);
+ todo_wine ok(hThread != NULL,
+ "CreateRemoteThread failed, err=%lu\n", GetLastError());
+ ret = WaitForSingleObject(hThread, 100);
+ todo_wine ok(ret == WAIT_OBJECT_0,
+ "waiting for thread failed, ret=%lu\n", ret);
+ CloseHandle(hThread);
+
+ /* create remote thread with entry point SetEvent() */
+ hThread = CreateRemoteThread(hProcess, NULL, 0,
+ threadFunc_SetEvent,
+ hRemoteEvent, 0, &tid);
+ todo_wine ok(hThread != NULL,
+ "CreateRemoteThread failed, err=%lu\n", GetLastError());
+
+ /* closed handle, so wait times out */
+ ret = WaitForSingleObject(hEvent, 100);
+ ok(ret == WAIT_TIMEOUT, "wait did not time out, ret=%lu\n", ret);
+
+ /* check that remote SetEvent() failed */
+ ret = GetExitCodeThread(hThread, &exitcode);
+ todo_wine ok(ret != 0,
+ "GetExitCodeThread failed, err=%lu\n", GetLastError());
+ todo_wine ok(exitcode == 0,
+ "SetEvent succeeded, expected to fail\n");
+ CloseHandle(hThread);
+
+ TerminateProcess(hProcess, 0);
+ CloseHandle(hEvent);
+ CloseHandle(hProcess);
+}
+
+static DWORD WINAPI create_remote_thread_worker(LPVOID lpParameter)
+{
+ while (WaitForSingleObject(hStressTestQuitEvent, 0) != WAIT_OBJECT_0)
+ {
+ HANDLE hThread;
+ hThread = CreateRemoteThread(hStressTestProcess, NULL, 0,
+ threadFunc2, NULL, 0, NULL);
+ todo_wine ok(hThread != NULL, "CreateRemoteThread failed, error %lu\n",
+ GetLastError());
+ todo_wine ok(WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0,
+ "Remote thread did not exit in time\n");
+ if (hThread == NULL) break;
+ CloseHandle(hThread);
+ }
+ return 0;
+}
+
+/* mini stress test for CreateRemoteThread */
+static VOID test_CreateRemoteThread_ministress(void)
+{
+ mini_stress_test(create_remote_thread_worker, "remote thread");
+}
+
/* Check basic funcationality of CreateThread and Tls* functions */
static VOID test_CreateThread_basic(void)
{
@@ -723,6 +841,9 @@ static void test_QueueUserWorkItem(void)
START_TEST(thread)
{
HINSTANCE lib;
+ int argc;
+ char **argv;
+ argc = winetest_get_mainargs( &argv );
/* Neither Cygwin nor mingW export OpenThread, so do a dynamic check
so that the compile passes
*/
@@ -733,6 +854,30 @@ START_TEST(thread)
pQueueUserWorkItem=(QueueUserWorkItem_t)GetProcAddress(lib,"QueueUserWorkItem");
pSetThreadIdealProcessor=(SetThreadIdealProcessor_t)GetProcAddress(lib,"SetThreadIdealProcessor");
pSetThreadPriorityBoost=(SetThreadPriorityBoost_t)GetProcAddress(lib,"SetThreadPriorityBoost");
+
+ if (argc >= 3)
+ {
+ if (!strcmp(argv[2], "sleep"))
+ {
+ Sleep(5000); /* spawned process runs for at most 5 seconds */
+ return;
+ }
+ while (1)
+ {
+ HANDLE hThread;
+ hThread = CreateThread(NULL, 0, threadFunc2, NULL, 0, NULL);
+ ok(hThread != NULL, "CreateThread failed, error %lu\n",
+ GetLastError());
+ ok(WaitForSingleObject(hThread, 200) == WAIT_OBJECT_0,
+ "Thread did not exit in time\n");
+ if (hThread == NULL) break;
+ CloseHandle(hThread);
+ }
+ return;
+ }
+
+ test_CreateRemoteThread();
+ test_CreateRemoteThread_ministress();
test_CreateThread_basic();
test_CreateThread_suspended();
test_SuspendThread();
More information about the wine-patches
mailing list