Commit 82fd2540 by Jamie Madill Committed by Commit Bot

Windows: Use Job handle in LaunchProcess.

This forces all child processes to quit when the parent process is unexpectedly terminated. Disabled on Windows 7 because it seems to fail with assinging the process to the job object. Possibly because of permission conflicts with the Chromium base/test launcher. Bug: angleproject:3162 Change-Id: I35f1c1ac5c802904b9b7220cab1bafce1ae0ea15 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1862989Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent f18ff947
...@@ -8,17 +8,16 @@ ...@@ -8,17 +8,16 @@
#include "util/test_utils.h" #include "util/test_utils.h"
#include <aclapi.h>
#include <stdarg.h> #include <stdarg.h>
#include <versionhelpers.h>
#include <windows.h> #include <windows.h>
#include <array> #include <array>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <aclapi.h>
#include "common/angleutils.h"
#include "anglebase/no_destructor.h" #include "anglebase/no_destructor.h"
#include "common/angleutils.h"
#include "util/windows/third_party/StackWalker/src/StackWalker.h" #include "util/windows/third_party/StackWalker/src/StackWalker.h"
namespace angle namespace angle
...@@ -218,6 +217,12 @@ bool ReturnSuccessOnNotFound() ...@@ -218,6 +217,12 @@ bool ReturnSuccessOnNotFound()
return (error_code == ERROR_FILE_NOT_FOUND || error_code == ERROR_PATH_NOT_FOUND); return (error_code == ERROR_FILE_NOT_FOUND || error_code == ERROR_PATH_NOT_FOUND);
} }
// Job objects seems to have problems on the Chromium CI and Windows 7.
bool ShouldUseJobObjects()
{
return (::IsWindows10OrGreater());
}
class WindowsProcess : public Process class WindowsProcess : public Process
{ {
public: public:
...@@ -284,6 +289,28 @@ class WindowsProcess : public Process ...@@ -284,6 +289,28 @@ class WindowsProcess : public Process
startInfo.dwFlags |= STARTF_USESTDHANDLES; startInfo.dwFlags |= STARTF_USESTDHANDLES;
} }
if (ShouldUseJobObjects())
{
// Create job object. Job objects allow us to automatically force child processes to
// exit if the parent process is unexpectedly killed. This should prevent ghost
// processes from hanging around.
mJobHandle = ::CreateJobObjectA(nullptr, nullptr);
if (mJobHandle == NULL)
{
std::cerr << "Error creating job object: " << GetLastError() << "\n";
return;
}
JOBOBJECT_EXTENDED_LIMIT_INFORMATION limitInfo = {};
limitInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (::SetInformationJobObject(mJobHandle, JobObjectExtendedLimitInformation, &limitInfo,
sizeof(limitInfo)) == FALSE)
{
std::cerr << "Error setting job information: " << GetLastError() << "\n";
return;
}
}
// Create the child process. // Create the child process.
if (::CreateProcessA(nullptr, commandLineString.data(), nullptr, nullptr, if (::CreateProcessA(nullptr, commandLineString.data(), nullptr, nullptr,
TRUE, // Handles are inherited. TRUE, // Handles are inherited.
...@@ -293,6 +320,15 @@ class WindowsProcess : public Process ...@@ -293,6 +320,15 @@ class WindowsProcess : public Process
return; return;
} }
if (mJobHandle != nullptr)
{
if (::AssignProcessToJobObject(mJobHandle, mProcessInfo.hProcess) == FALSE)
{
std::cerr << "AssignProcessToJobObject failed: " << GetLastError() << "\n";
return;
}
}
// Close the write end of the pipes, so EOF can be generated when child exits. // Close the write end of the pipes, so EOF can be generated when child exits.
if (!mStdoutPipe.closeWriteHandle() || !mStderrPipe.closeWriteHandle()) if (!mStdoutPipe.closeWriteHandle() || !mStderrPipe.closeWriteHandle())
return; return;
...@@ -311,6 +347,10 @@ class WindowsProcess : public Process ...@@ -311,6 +347,10 @@ class WindowsProcess : public Process
{ {
::CloseHandle(mProcessInfo.hThread); ::CloseHandle(mProcessInfo.hThread);
} }
if (mJobHandle != nullptr)
{
::CloseHandle(mJobHandle);
}
} }
bool started() override { return mStarted; } bool started() override { return mStarted; }
...@@ -416,6 +456,7 @@ class WindowsProcess : public Process ...@@ -416,6 +456,7 @@ class WindowsProcess : public Process
ScopedPipe mStdoutPipe; ScopedPipe mStdoutPipe;
ScopedPipe mStderrPipe; ScopedPipe mStderrPipe;
PROCESS_INFORMATION mProcessInfo = {}; PROCESS_INFORMATION mProcessInfo = {};
HANDLE mJobHandle = nullptr;
}; };
} // anonymous namespace } // anonymous namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment