Browse Source

Merge topic 'process-timeout-terminate'

3dc641d99c Merge branch 'backport-3.31-process-timeout-terminate'
22e84c7e7f execute_process: Restore termination of processes on timeout
e2cfc61e5e execute_process: Restore termination of processes on timeout

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !11408
Brad King 3 weeks ago
parent
commit
3529a96ba5

+ 2 - 0
Source/CTest/cmCTestBuildAndTest.cxx

@@ -123,6 +123,8 @@ bool cmCTestBuildAndTest::RunTest(std::vector<std::string> const& argv,
         std::cout << "\n*** Exception executing: " << exception.second;
       } break;
     }
+  } else {
+    chain.Terminate();
   }
 
   return result;

+ 1 - 0
Source/CTest/cmCTestBuildHandler.cxx

@@ -1010,6 +1010,7 @@ bool cmCTestBuildHandler::RunMakeCommand(std::string const& command,
         break;
     }
   } else {
+    chain.Terminate();
     cmCTestOptionalLog(this->CTest, WARNING,
                        "There was a timeout" << std::endl, this->Quiet);
   }

+ 2 - 0
Source/cmCTest.cxx

@@ -999,6 +999,7 @@ bool cmCTest::RunMakeCommand(std::string const& command, std::string& output,
         break;
     }
   } else {
+    chain.Terminate();
     cmCTestLog(this, WARNING, "There was a timeout" << std::endl);
   }
 
@@ -3341,6 +3342,7 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
 
   bool result = true;
   if (timedOut) {
+    chain.Terminate();
     char const* error_str = "Process terminated due to timeout\n";
     cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl);
     stdErr->append(error_str, strlen(error_str));

+ 3 - 0
Source/cmExecuteProcessCommand.cxx

@@ -405,6 +405,9 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
          !(chain.Finished() && outputData.Finished && errorData.Finished)) {
     uv_run(&chain.GetLoop(), UV_RUN_ONCE);
   }
+  if (timedOut) {
+    chain.Terminate();
+  }
   if (!arguments.OutputQuiet &&
       (arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
     processOutput.DecodeText(std::string(), strdata, 1);

+ 1 - 0
Source/cmSystemTools.cxx

@@ -976,6 +976,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
 
   bool result = true;
   if (timedOut) {
+    chain.Terminate();
     char const* error_str = "Process terminated due to timeout\n";
     if (outputflag != OUTPUT_NONE) {
       std::cerr << error_str << std::endl;

+ 17 - 0
Source/cmUVProcessChain.cxx

@@ -12,6 +12,8 @@
 
 #include <cm3p/uv.h>
 
+#include "cmsys/Process.h"
+
 #include "cm_fileno.hxx"
 
 #include "cmGetPipes.h"
@@ -58,6 +60,7 @@ struct cmUVProcessChain::InternalData
     cmUVProcessChainBuilder::ProcessConfiguration const& config, bool first,
     bool last);
   void Finish();
+  void Terminate();
 };
 
 cmUVProcessChainBuilder::cmUVProcessChainBuilder() = default;
@@ -403,6 +406,15 @@ void cmUVProcessChain::InternalData::Finish()
   this->Valid = true;
 }
 
+void cmUVProcessChain::InternalData::Terminate()
+{
+  for (std::unique_ptr<ProcessData> const& p : this->Processes) {
+    if (!p->ProcessStatus.Finished) {
+      cmsysProcess_KillPID(static_cast<unsigned long>(p->Process->pid));
+    }
+  }
+}
+
 cmUVProcessChain::cmUVProcessChain()
   : Data(cm::make_unique<InternalData>())
 {
@@ -487,6 +499,11 @@ bool cmUVProcessChain::Finished() const
   return this->Data->ProcessesCompleted >= this->Data->Processes.size();
 }
 
+void cmUVProcessChain::Terminate()
+{
+  this->Data->Terminate();
+}
+
 std::pair<cmUVProcessChain::ExceptionCode, std::string>
 cmUVProcessChain::Status::GetException() const
 {

+ 4 - 0
Source/cmUVProcessChain.h

@@ -117,6 +117,10 @@ public:
   Status const& GetStatus(std::size_t index) const;
   bool Finished() const;
 
+  /** Terminate any remaining child processes.
+      Call this only after exiting the event loop, and at most once.  */
+  void Terminate();
+
 private:
   friend class cmUVProcessChainBuilder;