mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-05 19:10:19 +00:00
Implement memoryLimit on Windows.
llvm-svn: 34922
This commit is contained in:
parent
b58af23ff3
commit
5506bc49f9
@ -93,8 +93,8 @@ static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) {
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
|
||||
(fd ? "input: " : "output: "));
|
||||
return h;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ Program::ExecuteAndWait(const Path& path,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
|
||||
@ -204,6 +204,35 @@ Program::ExecuteAndWait(const Path& path,
|
||||
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.
|
||||
DWORD millisecondsToWait = INFINITE;
|
||||
if (secondsToWait > 0)
|
||||
@ -223,10 +252,6 @@ Program::ExecuteAndWait(const Path& path,
|
||||
rc = GetExitCodeProcess(pi.hProcess, &status);
|
||||
err = GetLastError();
|
||||
|
||||
// Done with the handles; go close them.
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
if (!rc) {
|
||||
SetLastError(err);
|
||||
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);
|
||||
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…
x
Reference in New Issue
Block a user