summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2015-05-28 13:35:08 +0200
committerNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2015-06-01 13:08:15 +0000
commitd5db236fd5d51bfa237013f4796902ccb4d5b6b3 (patch)
treec58f614035c706ff9ac174bed0fe773adf31fe33
parentc58de2bb4a5c4b4c808273282c72f81c065e609d (diff)
downloadqt-creator-wip/clang-oop.tar.gz
ConnectionClient: Fix race conditions regarding the timeoutwip/clang-oop
If the main thread is blocked for a while, it is unclear whether first the timeout slot is processed or the data from the socket. Change-Id: Ief1fdf40968f7548a0ad5ca4abc9b40253f79fa8 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
-rw-r--r--src/libs/codemodelbackendipc/connectionclient.cpp23
-rw-r--r--src/libs/codemodelbackendipc/connectionclient.h2
2 files changed, 22 insertions, 3 deletions
diff --git a/src/libs/codemodelbackendipc/connectionclient.cpp b/src/libs/codemodelbackendipc/connectionclient.cpp
index 61c12e4629..de3b9b7649 100644
--- a/src/libs/codemodelbackendipc/connectionclient.cpp
+++ b/src/libs/codemodelbackendipc/connectionclient.cpp
@@ -53,11 +53,14 @@ QString connectionName()
}
ConnectionClient::ConnectionClient(IpcClientInterface *client)
- : serverProxy_(client, &localSocket)
+ : serverProxy_(client, &localSocket),
+ isAliveTimerResetted(false)
{
processAliveTimer.setInterval(10000);
- connect(&processAliveTimer, &QTimer::timeout, this, &ConnectionClient::restartProcess);
+ connect(&processAliveTimer, &QTimer::timeout,
+ this, &ConnectionClient::restartProcessIfTimerIsNotResettedAndSocketIsEmpty);
+
connect(&localSocket,
static_cast<void (QLocalSocket::*)(QLocalSocket::LocalSocketError)>(&QLocalSocket::error),
this,
@@ -112,6 +115,7 @@ void ConnectionClient::sendEndCommand()
void ConnectionClient::resetProcessAliveTimer()
{
+ isAliveTimerResetted = true;
processAliveTimer.start();
}
@@ -127,7 +131,7 @@ void ConnectionClient::startProcess()
connectStandardOutputAndError();
process()->start(processPath(), {connectionName()});
process()->waitForStarted();
- processAliveTimer.start();
+ resetProcessAliveTimer();
}
}
@@ -141,6 +145,19 @@ void ConnectionClient::restartProcess()
emit processRestarted();
}
+void ConnectionClient::restartProcessIfTimerIsNotResettedAndSocketIsEmpty()
+{
+ if (isAliveTimerResetted) {
+ isAliveTimerResetted = false;
+ return; // Already reset, but we were scheduled after.
+ }
+
+ if (localSocket.bytesAvailable() > 0)
+ return; // We come first, the incoming data was not yet processed.
+
+ restartProcess();
+}
+
bool ConnectionClient::connectToLocalSocket()
{
QThread::msleep(30);
diff --git a/src/libs/codemodelbackendipc/connectionclient.h b/src/libs/codemodelbackendipc/connectionclient.h
index 2e2cb2ef15..fb5d2b4f35 100644
--- a/src/libs/codemodelbackendipc/connectionclient.h
+++ b/src/libs/codemodelbackendipc/connectionclient.h
@@ -70,6 +70,7 @@ public:
void startProcess();
void restartProcess();
+ void restartProcessIfTimerIsNotResettedAndSocketIsEmpty();
void finishProcess();
bool isProcessIsRunning() const;
@@ -104,6 +105,7 @@ private:
IpcServerProxy serverProxy_;
QTimer processAliveTimer;
QString processPath_;
+ bool isAliveTimerResetted;
};
} // namespace CodeModelBackEnd