Fix a race condition in getting the process exit code on Win32.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77953 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2009-08-03 05:02:46 +00:00
parent 4bd03abe59
commit defc85327a
3 changed files with 31 additions and 8 deletions

View File

@ -29,6 +29,9 @@ namespace sys {
/// @since 1.4 /// @since 1.4
/// @brief An abstraction for finding and executing programs. /// @brief An abstraction for finding and executing programs.
class Program { class Program {
/// Opaque handle for target specific data.
void *Data;
unsigned Pid_; unsigned Pid_;
// Noncopyable. // Noncopyable.
@ -39,8 +42,8 @@ namespace sys {
/// @{ /// @{
public: public:
Program() : Pid_(0) Program();
{} ~Program();
/// Return process ID of this program. /// Return process ID of this program.
unsigned GetPid() { return Pid_; } unsigned GetPid() { return Pid_; }

View File

@ -35,6 +35,10 @@
namespace llvm { namespace llvm {
using namespace sys; using namespace sys;
Program::Program() : Pid_(0) {}
Program::~Program() {}
// This function just uses the PATH environment variable to find the program. // This function just uses the PATH environment variable to find the program.
Path Path
Program::FindProgramByName(const std::string& progName) { Program::FindProgramByName(const std::string& progName) {

View File

@ -25,6 +25,16 @@
namespace llvm { namespace llvm {
using namespace sys; using namespace sys;
Program::Program() : Pid_(0), Data(0) {}
Program::~Program() {
if (Data) {
HANDLE hProcess = (HANDLE) Data;
CloseHandle(hProcess);
Data = 0;
}
}
// This function just uses the PATH environment variable to find the program. // This function just uses the PATH environment variable to find the program.
Path Path
Program::FindProgramByName(const std::string& progName) { Program::FindProgramByName(const std::string& progName) {
@ -122,6 +132,12 @@ Program::Execute(const Path& path,
const Path** redirects, const Path** redirects,
unsigned memoryLimit, unsigned memoryLimit,
std::string* ErrMsg) { std::string* ErrMsg) {
if (Data) {
HANDLE hProcess = (HANDLE) Data;
CloseHandle(Data);
Data = 0;
}
if (!path.canExecute()) { if (!path.canExecute()) {
if (ErrMsg) if (ErrMsg)
*ErrMsg = "program not executable"; *ErrMsg = "program not executable";
@ -250,9 +266,9 @@ Program::Execute(const Path& path,
return false; return false;
} }
Pid_ = pi.dwProcessId; Pid_ = pi.dwProcessId;
Data = pi.hProcess;
// Make sure these get closed no matter what. // Make sure these get closed no matter what.
AutoHandle hProcess(pi.hProcess);
AutoHandle hThread(pi.hThread); AutoHandle hThread(pi.hThread);
// Assign the process to a job if a memory limit is defined. // Assign the process to a job if a memory limit is defined.
@ -286,12 +302,12 @@ Program::Execute(const Path& path,
int int
Program::Wait(unsigned secondsToWait, Program::Wait(unsigned secondsToWait,
std::string* ErrMsg) { std::string* ErrMsg) {
if (Pid_ == 0) { if (Data == 0) {
MakeErrMsg(ErrMsg, "Process not started!"); MakeErrMsg(ErrMsg, "Process not started!");
return -1; return -1;
} }
AutoHandle hProcess = OpenProcess(SYNCHRONIZE, FALSE, Pid_); HANDLE hProcess = (HANDLE) Data;
// Wait for the process to terminate. // Wait for the process to terminate.
DWORD millisecondsToWait = INFINITE; DWORD millisecondsToWait = INFINITE;