From d5db236fd5d51bfa237013f4796902ccb4d5b6b3 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 28 May 2015 13:35:08 +0200 Subject: ConnectionClient: Fix race conditions regarding the timeout 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 --- src/libs/codemodelbackendipc/connectionclient.cpp | 23 ++++++++++++++++++++--- 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(&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 -- cgit v1.2.1