summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-03-22 14:27:39 (GMT)
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-03-25 10:43:14 (GMT)
commite7a760fe7d20b5c3da53e2daa415ac09865da78c (patch)
tree55aeb8186bec8b1abf9b07c832306dabed14ef47
parent89abbdd8c8db5bf587373f2a00f6a816eddd8496 (diff)
downloadCMake-e7a760fe7d20b5c3da53e2daa415ac09865da78c.zip
CMake-e7a760fe7d20b5c3da53e2daa415ac09865da78c.tar.gz
CMake-e7a760fe7d20b5c3da53e2daa415ac09865da78c.tar.bz2
Autogen: Fix deadlock when uv_spawn() fails while trying to run moc
If by some chance the moc executable does not exist while running AUTOMOC, instead of showing an error, the CMake Autogen invocation hangs indefinitely. This happens because UVProcessFinished() is not called if the process does not launch correctly. Make sure to call UVProcessFinished() even if the process launch fails, and also report the error returned by libuv.
-rw-r--r--Source/cmQtAutoGenerator.cxx14
-rw-r--r--Source/cmQtAutoGeneratorMocUic.cxx6
2 files changed, 17 insertions, 3 deletions
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index a1abd3f..27afe48 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmake.h"
#include <algorithm>
+#include <sstream>
#include <utility>
// -- Class methods
@@ -504,6 +505,13 @@ void cmQtAutoGenerator::ReadOnlyProcessT::setup(
Setup_.MergedOutput = mergedOutput;
}
+static std::string getUVError(const char* prefixString, int uvErrorCode)
+{
+ std::ostringstream ost;
+ ost << prefixString << ": " << uv_strerror(uvErrorCode);
+ return ost.str();
+}
+
bool cmQtAutoGenerator::ReadOnlyProcessT::start(
uv_loop_t* uv_loop, std::function<void()>&& finishedCallback)
{
@@ -560,8 +568,10 @@ bool cmQtAutoGenerator::ReadOnlyProcessT::start(
UVOptions_.stdio = UVOptionsStdIO_.data();
// -- Spawn process
- if (UVProcess_.spawn(*uv_loop, UVOptions_, this) != 0) {
- Result()->ErrorMessage = "libuv process spawn failed";
+ int uvErrorCode = UVProcess_.spawn(*uv_loop, UVOptions_, this);
+ if (uvErrorCode != 0) {
+ Result()->ErrorMessage =
+ getUVError("libuv process spawn failed ", uvErrorCode);
}
}
// -- Start reading from stdio streams
diff --git a/Source/cmQtAutoGeneratorMocUic.cxx b/Source/cmQtAutoGeneratorMocUic.cxx
index cb6f7ea..0982473 100644
--- a/Source/cmQtAutoGeneratorMocUic.cxx
+++ b/Source/cmQtAutoGeneratorMocUic.cxx
@@ -1107,13 +1107,17 @@ void cmQtAutoGeneratorMocUic::WorkerT::UVProcessStart(uv_async_t* handle)
wrk.Process_->start(handle->loop, [&wrk] { wrk.UVProcessFinished(); });
}
}
+
+ if (!wrk.Process_->IsStarted()) {
+ wrk.UVProcessFinished();
+ }
}
void cmQtAutoGeneratorMocUic::WorkerT::UVProcessFinished()
{
{
std::lock_guard<std::mutex> lock(ProcessMutex_);
- if (Process_ && Process_->IsFinished()) {
+ if (Process_ && (Process_->IsFinished() || !Process_->IsStarted())) {
Process_.reset();
}
}