diff --git a/lib/Basic/Unix/TaskQueue.inc b/lib/Basic/Unix/TaskQueue.inc index 3aaf9ffe93d29..bfd46a68797d6 100644 --- a/lib/Basic/Unix/TaskQueue.inc +++ b/lib/Basic/Unix/TaskQueue.inc @@ -114,6 +114,18 @@ public: "Env must either be empty or null-terminated!"); } + ~Task() { + // Ensure pipes are closed when the task is destroyed + if (Pipe >= 0) { + close(Pipe); + Pipe = -1; + } + if (ErrorPipe >= 0) { + close(ErrorPipe); + ErrorPipe = -1; + } + } + const char *getExecPath() const { return ExecPath; } ArrayRef getArgs() const { return Args; } StringRef getOutput() const { return Output; } diff --git a/unittests/Basic/TaskQueueTest.cpp b/unittests/Basic/TaskQueueTest.cpp index 460db418551a4..85085d3f496a7 100644 --- a/unittests/Basic/TaskQueueTest.cpp +++ b/unittests/Basic/TaskQueueTest.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -93,9 +94,15 @@ TEST(TaskQueueTest, TaskSignalHandling) { bool TaskSignalled = false; int ReceivedSignal = 0; ProcessId ChildPid = 0; + std::mutex PidMutex; + std::condition_variable PidCv; auto TaskBegan = [&](ProcessId Pid, void *Context) { - ChildPid = Pid; + { + std::lock_guard lock(PidMutex); + ChildPid = Pid; + } + PidCv.notify_one(); }; auto TaskSignalledCallback = [&](ProcessId Pid, llvm::StringRef ErrorMsg, @@ -117,7 +124,11 @@ TEST(TaskQueueTest, TaskSignalHandling) { TQ.execute(TaskBegan, nullptr, TaskSignalledCallback); }); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + // Wait for the task to actually start and get its PID + { + std::unique_lock lock(PidMutex); + PidCv.wait_for(lock, std::chrono::seconds(5), [&] { return ChildPid > 0; }); + } if (ChildPid > 0) { EXPECT_EQ(0, kill(ChildPid, SIGTERM)) << "Should kill the specific child process we spawned";