From 49e06798642e2fcbf1b3c74b040b2ec1bc8a85e0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 1 Oct 2023 17:46:27 -0500 Subject: [PATCH] Synchronize with possible concurrent writers to the NvComputer object --- app/backend/computermanager.cpp | 3 +++ app/backend/computermanager.h | 2 +- app/backend/nvcomputer.h | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/backend/computermanager.cpp b/app/backend/computermanager.cpp index 8a273eb9..185a4598 100644 --- a/app/backend/computermanager.cpp +++ b/app/backend/computermanager.cpp @@ -257,6 +257,7 @@ void DelayedFlushThread::run() { for (const NvComputer* computer : m_ComputerManager->m_KnownHosts) { // Copy the current state of the NvComputer to allow us to check later if we need // to serialize it again when attribute updates occur. + QReadLocker computerLock(&computer->lock); m_ComputerManager->m_LastSerializedHosts[computer->uuid] = *computer; } } @@ -446,8 +447,10 @@ void ComputerManager::saveHost(NvComputer *computer) { // If no serializable properties changed, don't bother saving hosts QMutexLocker lock(&m_DelayedFlushMutex); + QReadLocker computerLock(&computer->lock); if (!m_LastSerializedHosts.value(computer->uuid).isEqualSerialized(*computer)) { // Queue a request for a delayed flush to QSettings outside of the lock + computerLock.unlock(); lock.unlock(); saveHosts(); } diff --git a/app/backend/computermanager.h b/app/backend/computermanager.h index 351f3c7a..20c93650 100644 --- a/app/backend/computermanager.h +++ b/app/backend/computermanager.h @@ -267,7 +267,7 @@ private: QVector m_PendingResolution; CompatFetcher m_CompatFetcher; DelayedFlushThread* m_DelayedFlushThread; - QMutex m_DelayedFlushMutex; + QMutex m_DelayedFlushMutex; // Lock ordering: Must never be acquired while holding NvComputer lock QWaitCondition m_DelayedFlushCondition; bool m_NeedsDelayedFlush; }; diff --git a/app/backend/nvcomputer.h b/app/backend/nvcomputer.h index ab9e0b30..3610188c 100644 --- a/app/backend/nvcomputer.h +++ b/app/backend/nvcomputer.h @@ -34,8 +34,10 @@ private: public: NvComputer() = default; - NvComputer(const NvComputer& other) = default; + // Caller is responsible for synchronizing read access to the other host + NvComputer(const NvComputer&) = default; + // Caller is responsible for synchronizing read access to the other host NvComputer& operator=(const NvComputer &) = default; explicit NvComputer(NvHTTP& http, QString serverInfo); @@ -67,6 +69,7 @@ public: void serialize(QSettings& settings, bool serializeApps) const; + // Caller is responsible for synchronizing read access to both hosts bool isEqualSerialized(const NvComputer& that) const;