summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mainwindow.cpp34
-rw-r--r--src/mainwindow.h14
2 files changed, 38 insertions, 10 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 7d0496d..792ba3f 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1240,6 +1240,12 @@ void MainWindow::onSyncFinished(bool success, int exitCode)
// A sync is the usual way new tags enter the database.
requestAllTags();
} else if (exitCode == kSyncSkippedExitCode) {
+ // Skipped means the lock was never ours: some other run holds it. If
+ // both started inside the same poll interval the monitor will have
+ // latched this lock period as local, which would swallow the report
+ // when that other run finishes. Hand it back.
+ m_localSyncHoldsLock = false;
+
// Not a failure: another run holds the lock and is doing the work.
// The user's cron fires every ten minutes, so a click landing inside
// one is routine and must not raise an error or the log pane.
@@ -1300,15 +1306,27 @@ void MainWindow::onTagsApplied(const TagChange &change)
void MainWindow::onExternalSyncStateChanged(SyncMonitor::State state)
{
- // A sync this window started is already reported by setSyncBusy(), and the
- // monitor sees that lock too. Saying so twice would fight over the status
- // bar and would re-enable the progress bar as the local run finished.
- if (m_sync && m_sync->isRunning())
- return;
-
if (state == SyncMonitor::State::Running) {
+ // A sync this window started is already reported by setSyncBusy().
+ // Remember that this particular lock period is ours, because the
+ // release at the end of it must be ignored too: the process exits, and
+ // therefore isRunning() goes false, BEFORE the monitor's next poll sees
+ // the lock gone. Testing isRunning() again on that poll would report a
+ // local sync as an external one, stamping "background sync completed"
+ // over the local run's own result up to two seconds later.
+ m_localSyncHoldsLock = (m_sync && m_sync->isRunning());
+ if (m_localSyncHoldsLock)
+ return;
+
m_syncProgress->setVisible(true);
- m_statusLabel->setText(tr("Syncing (started elsewhere)..."));
+ m_statusLabel->setText(tr("Background sync running..."));
+ return;
+ }
+
+ // The release of a lock this window took. onSyncFinished() has already
+ // said what happened, including for a failure, so there is nothing to add.
+ if (m_localSyncHoldsLock) {
+ m_localSyncHoldsLock = false;
return;
}
@@ -1325,7 +1343,7 @@ void MainWindow::onExternalSyncStateChanged(SyncMonitor::State state)
// this cannot support.
if (state == SyncMonitor::State::Idle) {
m_statusLabel->setText(
- tr("Sync finished elsewhere. Press Enter in the query bar to "
+ tr("Background sync completed. Press Enter in the query bar to "
"refresh."));
}
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 57aceb1..66044dc 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -115,6 +115,12 @@ private slots:
void onWorkerError(const QString &message);
void onSyncFinished(bool success, int exitCode);
+ /// Reacts to a sync started outside this window, by cron or by hand.
+ ///
+ /// A private slot rather than a plain method so tests can drive it through
+ /// the meta-object without widening the public API.
+ void onExternalSyncStateChanged(SyncMonitor::State state);
+
/// A tag mutation the worker has confirmed reached the database. Counts it
/// as unsynced, since reaching the index is not reaching the mail store.
void onTagsApplied(const TagChange &change);
@@ -169,8 +175,6 @@ private:
/// says "working, duration unknown", which is the truth.
void setSyncBusy(bool busy);
- /// Reacts to a sync started outside this window, by cron or by hand.
- void onExternalSyncStateChanged(SyncMonitor::State state);
/// Opens the tag dialog on the current selection and applies its result.
///
@@ -213,6 +217,12 @@ private:
/// Watches the sync lock for runs this window did not start.
SyncMonitor *m_syncMonitor = nullptr;
+
+ /// True while the lock the monitor can see is held by this window's own
+ /// sync. Latched when the lock is taken, because by the time it is released
+ /// MailSync::isRunning() is already false and can no longer answer "was
+ /// that ours?".
+ bool m_localSyncHoldsLock = false;
QUndoStack m_undoStack;
QLineEdit *m_queryEdit = nullptr;