diff options
author | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2015-05-28 13:35:08 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2015-06-01 13:08:15 +0000 |
commit | d5db236fd5d51bfa237013f4796902ccb4d5b6b3 (patch) | |
tree | c58f614035c706ff9ac174bed0fe773adf31fe33 | |
parent | c58de2bb4a5c4b4c808273282c72f81c065e609d (diff) | |
download | qt-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.cpp | 23 | ||||
-rw-r--r-- | src/libs/codemodelbackendipc/connectionclient.h | 2 |
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 |