forked from OSchip/llvm-project
parent
50bf51e8ac
commit
a531d04b64
|
|
@ -93,8 +93,8 @@ static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) {
|
||||||
if (h == INVALID_HANDLE_VALUE) {
|
if (h == INVALID_HANDLE_VALUE) {
|
||||||
MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
|
MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
|
||||||
(fd ? "input: " : "output: "));
|
(fd ? "input: " : "output: "));
|
||||||
return h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +179,7 @@ Program::ExecuteAndWait(const Path& path,
|
||||||
0, TRUE, DUPLICATE_SAME_ACCESS);
|
0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
memset(&pi, 0, sizeof(pi));
|
memset(&pi, 0, sizeof(pi));
|
||||||
|
|
||||||
|
|
@ -204,6 +204,35 @@ Program::ExecuteAndWait(const Path& path,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure these get closed no matter what.
|
||||||
|
AutoHandle hProcess(pi.hProcess);
|
||||||
|
AutoHandle hThread(pi.hThread);
|
||||||
|
|
||||||
|
// Assign the process to a job if a memory limit is defined.
|
||||||
|
AutoHandle hJob(0);
|
||||||
|
if (memoryLimit != 0) {
|
||||||
|
hJob = CreateJobObject(0, 0);
|
||||||
|
bool success = false;
|
||||||
|
if (hJob != 0) {
|
||||||
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
|
||||||
|
memset(&jeli, 0, sizeof(jeli));
|
||||||
|
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY;
|
||||||
|
jeli.ProcessMemoryLimit = memoryLimit * 1048576;
|
||||||
|
if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation,
|
||||||
|
&jeli, sizeof(jeli))) {
|
||||||
|
if (AssignProcessToJobObject(hJob, pi.hProcess))
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
SetLastError(GetLastError());
|
||||||
|
MakeErrMsg(ErrMsg, std::string("Unable to set memory limit"));
|
||||||
|
TerminateProcess(pi.hProcess, 1);
|
||||||
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for it to terminate.
|
// Wait for it to terminate.
|
||||||
DWORD millisecondsToWait = INFINITE;
|
DWORD millisecondsToWait = INFINITE;
|
||||||
if (secondsToWait > 0)
|
if (secondsToWait > 0)
|
||||||
|
|
@ -223,10 +252,6 @@ Program::ExecuteAndWait(const Path& path,
|
||||||
rc = GetExitCodeProcess(pi.hProcess, &status);
|
rc = GetExitCodeProcess(pi.hProcess, &status);
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
|
|
||||||
// Done with the handles; go close them.
|
|
||||||
CloseHandle(pi.hProcess);
|
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
SetLastError(err);
|
SetLastError(err);
|
||||||
MakeErrMsg(ErrMsg, std::string("Failed getting status for program '") +
|
MakeErrMsg(ErrMsg, std::string("Failed getting status for program '") +
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,24 @@ inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
|
||||||
LocalFree(buffer);
|
LocalFree(buffer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AutoHandle {
|
||||||
|
HANDLE handle;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoHandle(HANDLE h) : handle(h) {}
|
||||||
|
|
||||||
|
~AutoHandle() {
|
||||||
|
if (handle)
|
||||||
|
CloseHandle(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator HANDLE() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoHandle &operator=(HANDLE h) {
|
||||||
|
handle = h;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue