diff --git a/src/blackmisc/datacache.cpp b/src/blackmisc/datacache.cpp index 9d9369c22..580ce4072 100644 --- a/src/blackmisc/datacache.cpp +++ b/src/blackmisc/datacache.cpp @@ -147,7 +147,7 @@ namespace BlackMisc void CDataCache::admitValue(const QString &key, bool triggerLoad) { - QTimer::singleShot(0, &m_serializer, [this, key] { m_revision.admitValue(key); }); + m_revision.admitValue(key); if (triggerLoad) { loadFromStoreAsync(); } } @@ -331,7 +331,7 @@ namespace BlackMisc if (json.contains("uuid") && json.contains("timestamps")) { QUuid uuid(json.value("uuid").toString()); - if (uuid == m_uuid) + if (uuid == m_uuid && m_admittedQueue.isEmpty()) { if (m_pendingWrite) { return guard; } return {}; @@ -365,6 +365,8 @@ namespace BlackMisc } auto deferrals = fromJson(json.value("deferrals").toArray()); + m_admittedValues.unite(m_admittedQueue); + if (updateUuid) { m_admittedQueue.clear(); } for (const auto &key : m_timestamps.keys()) { if (deferrals.contains(key) && ! m_admittedValues.contains(key)) { m_timestamps.remove(key); } @@ -463,7 +465,10 @@ namespace BlackMisc { QMutexLocker lock(&m_mutex); - return (m_updateInProgress || m_pendingWrite || beginUpdate({{ key, timestamp }}, false)) && m_timestamps.contains(key); + // Temporary guard object returned by beginUpdate is deleted at the end of the full expression, + // don't try to split the conditional into multiple statements. + return (m_updateInProgress || m_pendingWrite || beginUpdate({{ key, timestamp }}, false)) + && (m_timestamps.contains(key) || m_admittedQueue.contains(key)); } std::future CDataCacheRevision::promiseLoadedValue(const QString &key, qint64 currentTimestamp) @@ -569,9 +574,9 @@ namespace BlackMisc void CDataCacheRevision::admitValue(const QString &key) { - Q_ASSERT(! m_updateInProgress); + QMutexLocker lock(&m_mutex); - m_admittedValues.insert(key); + m_admittedQueue.insert(key); } QJsonObject CDataCacheRevision::toJson(const QMap ×tamps) diff --git a/src/blackmisc/datacache.h b/src/blackmisc/datacache.h index c03a44df5..7fa8bcb3b 100644 --- a/src/blackmisc/datacache.h +++ b/src/blackmisc/datacache.h @@ -163,6 +163,7 @@ namespace BlackMisc QSet m_pinnedValues; QSet m_deferredValues; QSet m_admittedValues; + QSet m_admittedQueue; std::vector> m_promises; static QJsonObject toJson(const QMap ×tamps); @@ -311,7 +312,7 @@ namespace BlackMisc void renewTimestamp(qint64 timestamp) { return CDataCache::instance()->renewTimestamp(this->getKey(), timestamp); } //! If the value is load-deferred, trigger the deferred load (async). - void admit() { CDataCache::instance()->admitValue(Trait::key(), true); } + void admit() { if (Trait::isDeferred()) { CDataCache::instance()->admitValue(Trait::key(), true); } } //! If the value is currently being loaded, wait for it to finish loading, and call the notification slot, if any. void synchronize()