diff options
author | Ivan Komissarov <ABBAPOH@gmail.com> | 2020-05-31 17:02:24 +0200 |
---|---|---|
committer | Ivan Komissarov <ABBAPOH@gmail.com> | 2020-07-30 09:23:03 +0000 |
commit | 6fb6fcd112435faed9f05165bc4de35ebb1b8d03 (patch) | |
tree | d6995cd9871c060f815121bc569f1281242839fc | |
parent | 215c78da617621d4301fd0f9e78a8873a3ef9a0e (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.cpp | 3 | ||||
-rw-r--r-- | src/lib/corelib/tools/launchersocket.cpp | 31 | ||||
-rw-r--r-- | src/lib/corelib/tools/launchersocket.h | 4 |
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; |