From 7726267d071cb0c3d6dfad8ee4d1551140fcb06a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 13 Aug 2021 13:15:09 +0200 Subject: Fix a deadlock when doStart() is called from launcher's thread In case when QtcProcess::start() is being called very early, just after the launcher socket was started but not ready yet, a start is being delayed. In this case doStart() isn't called directly from the caller's thread, but it will be invoked later from the launcher's thread, when the socket is ready. In this case we may have a deadlock, since calling doStart(), sendPacket(), sendData() and finally handleRequests() results in a synchonous chain of calls in launcher's thread, so the mutex locked in sendData() will block synchronous call to handleRequests(). In order to fix it we unlock the mutex in sendData() before calling handleRequests(). Change-Id: I6c13994d0b05b624567c75ffbd2ac7cc0d77df61 Reviewed-by: hjk --- src/libs/utils/launchersocket.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/libs/utils/launchersocket.cpp b/src/libs/utils/launchersocket.cpp index 10fd7bb16f..429f8c2bf3 100644 --- a/src/libs/utils/launchersocket.cpp +++ b/src/libs/utils/launchersocket.cpp @@ -461,9 +461,15 @@ void LauncherSocket::sendData(const QByteArray &data) { if (!isReady()) return; - QMutexLocker locker(&m_mutex); - m_requests.push_back(data); - if (m_requests.size() == 1) + + auto storeRequest = [this](const QByteArray &data) + { + QMutexLocker locker(&m_mutex); + m_requests.push_back(data); + return m_requests.size() == 1; // Returns true if requests handling should be triggered. + }; + + if (storeRequest(data)) QMetaObject::invokeMethod(this, &LauncherSocket::handleRequests); } -- cgit v1.2.1