diff --git a/Telegram/SourceFiles/storage/cache/storage_cache_database.cpp b/Telegram/SourceFiles/storage/cache/storage_cache_database.cpp index fdfd31806..f3b25dbdd 100644 --- a/Telegram/SourceFiles/storage/cache/storage_cache_database.cpp +++ b/Telegram/SourceFiles/storage/cache/storage_cache_database.cpp @@ -39,6 +39,14 @@ void Database::close(FnMut &&done) { }); } +void Database::waitForCleaner(FnMut &&done) { + _wrapped.with([ + done = std::move(done) + ](Implementation &unwrapped) mutable { + unwrapped.waitForCleaner(std::move(done)); + }); +} + void Database::put( const Key &key, QByteArray &&value, diff --git a/Telegram/SourceFiles/storage/cache/storage_cache_database.h b/Telegram/SourceFiles/storage/cache/storage_cache_database.h index 3e9c4290f..f85e8fbfd 100644 --- a/Telegram/SourceFiles/storage/cache/storage_cache_database.h +++ b/Telegram/SourceFiles/storage/cache/storage_cache_database.h @@ -68,6 +68,7 @@ public: void clear(FnMut &&done = nullptr); void clearByTag(uint8 tag, FnMut &&done = nullptr); + void waitForCleaner(FnMut &&done = nullptr); ~Database(); diff --git a/Telegram/SourceFiles/storage/cache/storage_cache_database_object.cpp b/Telegram/SourceFiles/storage/cache/storage_cache_database_object.cpp index df21dd4a7..f47ccffbb 100644 --- a/Telegram/SourceFiles/storage/cache/storage_cache_database_object.cpp +++ b/Telegram/SourceFiles/storage/cache/storage_cache_database_object.cpp @@ -1167,6 +1167,7 @@ void DatabaseObject::createCleaner() { } void DatabaseObject::cleanerDone(Error error) { + invokeCallback(_cleaner.done); _cleaner = CleanerWrap(); pushStatsDelayed(); } @@ -1211,6 +1212,7 @@ void DatabaseObject::clear(FnMut &&done) { } if (key.empty()) { invokeCallback(done, Error::NoError()); + createCleaner(); return; } open(std::move(key), std::move(done)); @@ -1229,6 +1231,17 @@ void DatabaseObject::clearByTag(uint8 tag, FnMut &&done) { invokeCallback(done, Error::NoError()); } +void DatabaseObject::waitForCleaner(FnMut &&done) { + while (!_stale.empty()) { + clearStaleChunk(); + } + if (_cleaner.object) { + _cleaner.done = std::move(done); + } else { + invokeCallback(done); + } +} + auto DatabaseObject::getManyRaw(const std::vector &keys) const -> std::vector { auto result = std::vector(); diff --git a/Telegram/SourceFiles/storage/cache/storage_cache_database_object.h b/Telegram/SourceFiles/storage/cache/storage_cache_database_object.h index 75e4ed4f6..e90e01479 100644 --- a/Telegram/SourceFiles/storage/cache/storage_cache_database_object.h +++ b/Telegram/SourceFiles/storage/cache/storage_cache_database_object.h @@ -59,6 +59,7 @@ public: void clear(FnMut &&done); void clearByTag(uint8 tag, FnMut &&done); + void waitForCleaner(FnMut &&done); static QString BinlogFilename(); static QString CompactReadyFilename(); @@ -90,6 +91,7 @@ private: struct CleanerWrap { std::unique_ptr object; base::binary_guard guard; + FnMut done; }; struct CompactorWrap { std::unique_ptr object; diff --git a/Telegram/SourceFiles/storage/storage_databases.cpp b/Telegram/SourceFiles/storage/storage_databases.cpp index 4fe5d6ba3..2d5353fdc 100644 --- a/Telegram/SourceFiles/storage/storage_databases.cpp +++ b/Telegram/SourceFiles/storage/storage_databases.cpp @@ -90,7 +90,8 @@ void Databases::destroy(Cache::Database *database) { Assert(!kept.destroying.alive()); auto [first, second] = base::make_binary_guard(); kept.destroying = std::move(first); - database->close([=, guard = std::move(second)]() mutable { + database->close(); + database->waitForCleaner([=, guard = std::move(second)]() mutable { crl::on_main([=, guard = std::move(guard)]{ if (!guard.alive()) { return; @@ -102,4 +103,4 @@ void Databases::destroy(Cache::Database *database) { } } -} // namespace Storage \ No newline at end of file +} // namespace Storage