diff options
author | Jonathan White <support@dmapps.us> | 2022-10-19 01:23:46 +0300 |
---|---|---|
committer | Jonathan White <support@dmapps.us> | 2022-10-19 17:16:17 +0300 |
commit | a6db8ba2db78a8385bc64c043c1cd7787fb61d97 (patch) | |
tree | e4f28b166bf4377c9436c833bc38653e53f87a7a | |
parent | 71b1df39ebe2b1d88d3bbbbd7d2ae71c87426478 (diff) |
Fix potential deadlock in UI when saving
This was noted as a problem in several issues and it finally occurred to me and I traced it to the fact that a timing issue sometimes allowed the file watcher to trigger a "file changed" alert right when saving starts. I fixed this by moving where the mutex lock is made for saving and preventing database reload during a save operation.
-rw-r--r-- | src/core/Database.cpp | 7 | ||||
-rw-r--r-- | src/gui/DatabaseWidget.cpp | 4 |
2 files changed, 6 insertions, 5 deletions
diff --git a/src/core/Database.cpp b/src/core/Database.cpp index 7a10f0483..508cbe51c 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -253,9 +253,6 @@ bool Database::saveAs(const QString& filePath, SaveAction action, const QString& return false; } - // Prevent destructive operations while saving - QMutexLocker locker(&m_saveMutex); - if (filePath == m_data.filePath) { // Fail-safe check to make sure we don't overwrite underlying file changes // that have not yet triggered a file reload/merge operation. @@ -270,6 +267,9 @@ bool Database::saveAs(const QString& filePath, SaveAction action, const QString& // Clear read-only flag m_fileWatcher->stop(); + // Prevent destructive operations while saving + QMutexLocker locker(&m_saveMutex); + QFileInfo fileInfo(filePath); auto realFilePath = fileInfo.exists() ? fileInfo.canonicalFilePath() : fileInfo.absoluteFilePath(); bool isNewFile = !QFile::exists(realFilePath); @@ -463,6 +463,7 @@ bool Database::import(const QString& xmlExportPath, QString* error) void Database::releaseData() { // Prevent data release while saving + Q_ASSERT(!isSaving()); QMutexLocker locker(&m_saveMutex); if (m_modified) { diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 64b4c4c77..ec5705914 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -1747,8 +1747,8 @@ bool DatabaseWidget::lock() void DatabaseWidget::reloadDatabaseFile() { - // Ignore reload if we are locked or currently editing an entry or group - if (!m_db || isLocked() || isEntryEditActive() || isGroupEditActive()) { + // Ignore reload if we are locked, saving, or currently editing an entry or group + if (!m_db || isLocked() || isEntryEditActive() || isGroupEditActive() || isSaving()) { return; } |