aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Komissarov <ABBAPOH@gmail.com>2020-05-31 17:02:24 +0200
committerIvan Komissarov <ABBAPOH@gmail.com>2020-07-30 09:23:03 +0000
commit6fb6fcd112435faed9f05165bc4de35ebb1b8d03 (patch)
treed6995cd9871c060f815121bc569f1281242839fc
parent215c78da617621d4301fd0f9e78a8873a3ef9a0e (diff)
Fix data race when calling LauncherSocket::isReady
According to C++ standard, it is not allowed to read/write non-atomic variable from different threads. Change-Id: Ia48a997b1f417ed68234afdcaad6d70c92d26064 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--src/lib/corelib/tools/launcherinterface.cpp3
-rw-r--r--src/lib/corelib/tools/launchersocket.cpp31
-rw-r--r--src/lib/corelib/tools/launchersocket.h4
3 files changed, 20 insertions, 18 deletions
diff --git a/src/lib/corelib/tools/launcherinterface.cpp b/src/lib/corelib/tools/launcherinterface.cpp
index 50ac659a9..d2cdf44df 100644
--- a/src/lib/corelib/tools/launcherinterface.cpp
+++ b/src/lib/corelib/tools/launcherinterface.cpp
@@ -128,8 +128,7 @@ void LauncherInterface::doStop()
if (!m_process)
return;
m_process->disconnect();
- if (m_socket->isReady())
- m_socket->shutdown();
+ m_socket->shutdown();
m_process->waitForFinished(3000);
m_process->deleteLater();
m_process = nullptr;
diff --git a/src/lib/corelib/tools/launchersocket.cpp b/src/lib/corelib/tools/launchersocket.cpp
index c7cfb27cf..1489af1e9 100644
--- a/src/lib/corelib/tools/launchersocket.cpp
+++ b/src/lib/corelib/tools/launchersocket.cpp
@@ -68,18 +68,19 @@ void LauncherSocket::sendData(const QByteArray &data)
void LauncherSocket::shutdown()
{
- QBS_ASSERT(m_socket, return);
- m_socket->disconnect();
- m_socket->write(ShutdownPacket().serialize());
- m_socket->waitForBytesWritten(1000);
- m_socket->deleteLater();
- m_socket = nullptr;
+ const auto socket = m_socket.exchange(nullptr);
+ if (!socket)
+ return;
+ socket->disconnect();
+ socket->write(ShutdownPacket().serialize());
+ socket->waitForBytesWritten(1000);
+ socket->deleteLater();
}
void LauncherSocket::setSocket(QLocalSocket *socket)
{
QBS_ASSERT(!m_socket, return);
- m_socket = socket;
+ m_socket.store(socket);
m_packetParser.setDevice(m_socket);
connect(m_socket,
#if (QT_VERSION < QT_VERSION_CHECK(5, 15, 0))
@@ -97,8 +98,9 @@ void LauncherSocket::setSocket(QLocalSocket *socket)
void LauncherSocket::handleSocketError()
{
- if (m_socket->error() != QLocalSocket::PeerClosedError)
- handleError(Tr::tr("Socket error: %1").arg(m_socket->errorString()));
+ auto socket = m_socket.load();
+ if (socket->error() != QLocalSocket::PeerClosedError)
+ handleError(Tr::tr("Socket error: %1").arg(socket->errorString()));
}
void LauncherSocket::handleSocketDataAvailable()
@@ -131,18 +133,19 @@ void LauncherSocket::handleSocketDisconnected()
void LauncherSocket::handleError(const QString &error)
{
- m_socket->disconnect();
- m_socket->deleteLater();
- m_socket = nullptr;
+ const auto socket = m_socket.exchange(nullptr);
+ socket->disconnect();
+ socket->deleteLater();
emit errorOccurred(error);
}
void LauncherSocket::handleRequests()
{
- QBS_ASSERT(isReady(), return);
+ const auto socket = m_socket.load();
+ QBS_ASSERT(socket, return);
std::lock_guard<std::mutex> locker(m_requestsMutex);
for (const QByteArray &request : qAsConst(m_requests))
- m_socket->write(request);
+ socket->write(request);
m_requests.clear();
}
diff --git a/src/lib/corelib/tools/launchersocket.h b/src/lib/corelib/tools/launchersocket.h
index a9a1af800..2eb2c3f63 100644
--- a/src/lib/corelib/tools/launchersocket.h
+++ b/src/lib/corelib/tools/launchersocket.h
@@ -60,7 +60,7 @@ class LauncherSocket : public QObject
Q_OBJECT
friend class LauncherInterface;
public:
- bool isReady() const { return m_socket; }
+ bool isReady() const { return m_socket.load(); }
void sendData(const QByteArray &data);
signals:
@@ -81,7 +81,7 @@ private:
void handleError(const QString &error);
void handleRequests();
- QLocalSocket *m_socket = nullptr;
+ std::atomic<QLocalSocket *> m_socket{nullptr};
PacketParser m_packetParser;
std::vector<QByteArray> m_requests;
std::mutex m_requestsMutex;