diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 663f1b16..7715f65c 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -3362,6 +3362,7 @@ if test "$enable_server_JobObjects" -eq 1; then patch_apply server-JobObjects/0012-server-Properly-track-handle-count-of-objects.patch patch_apply server-JobObjects/0014-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch patch_apply server-JobObjects/0014-server-Support-NULL-job-handles-in-IsProcessInJob.patch + patch_apply server-JobObjects/0015-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch ( echo '+ { "Sebastian Lackner", "kernel32/tests: Allow multiple subprocess commands in process tests.", 1 },'; echo '+ { "Andrew Cook", "kernel32/tests: Add tests for IsProcessInJob.", 1 },'; @@ -3377,6 +3378,7 @@ if test "$enable_server_JobObjects" -eq 1; then echo '+ { "Andrew Cook", "server: Properly track handle count of objects.", 1 },'; echo '+ { "Andrew Cook", "server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.", 1 },'; echo '+ { "Andrew Cook", "server: Support NULL job handles in IsProcessInJob.", 1 },'; + echo '+ { "Sebastian Lackner", "kernel32/tests: Add tests for waiting on an job object.", 1 },'; ) >> "$patchlist" fi diff --git a/patches/server-JobObjects/0015-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch b/patches/server-JobObjects/0015-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch new file mode 100644 index 00000000..73a2cd3b --- /dev/null +++ b/patches/server-JobObjects/0015-kernel32-tests-Add-tests-for-waiting-on-an-job-objec.patch @@ -0,0 +1,116 @@ +From 2d657a8a1efd0b526ea924996457940c7844b750 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 28 Feb 2015 06:09:16 +0100 +Subject: kernel32/tests: Add tests for waiting on an job object. + +--- + dlls/kernel32/tests/process.c | 86 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 86 insertions(+) + +diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c +index 110a770..bb1079c 100644 +--- a/dlls/kernel32/tests/process.c ++++ b/dlls/kernel32/tests/process.c +@@ -2460,6 +2460,91 @@ static void test_KillOnJobClose(void) + CloseHandle(pi.hThread); + } + ++static void test_WaitForJobObject(void) ++{ ++ HANDLE job; ++ PROCESS_INFORMATION pi; ++ BOOL ret; ++ DWORD dwret; ++ ++ /* test waiting for a job object when the process is killed */ ++ job = pCreateJobObjectW(NULL, NULL); ++ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); ++ ++ dwret = WaitForSingleObject(job, 100); ++ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret); ++ ++ create_process("wait", &pi); ++ ++ ret = pAssignProcessToJobObject(job, pi.hProcess); ++ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); ++ ++ dwret = WaitForSingleObject(job, 100); ++ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret); ++ ++ ret = pTerminateJobObject(job, 123); ++ ok(ret, "TerminateJobObject error %u\n", GetLastError()); ++ ++ dwret = WaitForSingleObject(job, 500); ++ todo_wine ++ ok(dwret == WAIT_OBJECT_0 || broken(dwret == WAIT_TIMEOUT), ++ "WaitForSingleObject returned %u\n", dwret); ++ ++ if (dwret == WAIT_TIMEOUT) /* Win 2000/XP */ ++ { ++ CloseHandle(pi.hProcess); ++ CloseHandle(pi.hThread); ++ CloseHandle(job); ++ todo_wine ++ win_skip("TerminateJobObject doesn't signal job, skipping tests\n"); ++ return; ++ } ++ ++ /* the object is not reset immediately */ ++ dwret = WaitForSingleObject(job, 100); ++ todo_wine ++ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); ++ ++ CloseHandle(pi.hProcess); ++ CloseHandle(pi.hThread); ++ ++ /* creating a new process doesn't reset the signalled state */ ++ create_process("wait", &pi); ++ ++ ret = pAssignProcessToJobObject(job, pi.hProcess); ++ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); ++ ++ dwret = WaitForSingleObject(job, 100); ++ ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret); ++ ++ ret = pTerminateJobObject(job, 123); ++ ok(ret, "TerminateJobObject error %u\n", GetLastError()); ++ ++ CloseHandle(pi.hProcess); ++ CloseHandle(pi.hThread); ++ ++ CloseHandle(job); ++ ++ /* repeat the test, but this time the process terminates properly */ ++ job = pCreateJobObjectW(NULL, NULL); ++ ok(job != NULL, "CreateJobObject error %u\n", GetLastError()); ++ ++ dwret = WaitForSingleObject(job, 100); ++ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret); ++ ++ create_process("exit", &pi); ++ ++ ret = pAssignProcessToJobObject(job, pi.hProcess); ++ ok(ret, "AssignProcessToJobObject error %u\n", GetLastError()); ++ ++ dwret = WaitForSingleObject(job, 100); ++ ok(dwret == WAIT_TIMEOUT, "WaitForSingleObject returned %u\n", dwret); ++ ++ CloseHandle(pi.hProcess); ++ CloseHandle(pi.hThread); ++ CloseHandle(job); ++} ++ + static HANDLE test_LimitActiveProcesses(void) + { + JOBOBJECT_BASIC_LIMIT_INFORMATION limit_info; +@@ -2715,6 +2800,7 @@ START_TEST(process) + test_QueryInformationJobObject(); + test_CompletionPort(); + test_KillOnJobClose(); ++ test_WaitForJobObject(); + job = test_LimitActiveProcesses(); + test_BreakawayOk(job); + CloseHandle(job); +-- +2.3.0 +