diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-07-20 20:39:09 +0300 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-07-21 22:42:36 +0300 |
| commit | 0f0e7e85076df6c71ea23b4bae2b0ed264e52291 (patch) | |
| tree | 201f20470927d53755feb9a4f924f936487837c0 | |
| parent | 70609524f38038f8d65810dcc088d9ff594982cc (diff) | |
#6014 Offload inventory cache packing onto a thread
| -rw-r--r-- | indra/newview/llappviewer.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.cpp | 58 | ||||
| -rw-r--r-- | indra/newview/llinventorymodel.h | 6 |
3 files changed, 58 insertions, 8 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 553517472e..6a236e9b2e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2160,6 +2160,8 @@ bool LLAppViewer::cleanup() SUBSYSTEM_CLEANUP(LLProxy); LLCore::LLHttp::cleanup(); + LLInventoryModel::waitForPendingCacheWrites(); + ll_close_fail_log(); LLError::LLCallStacks::cleanup(); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c72f1d2c35..f85d0eebae 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -82,6 +82,7 @@ const S32 LLInventoryModel::sCurrentInvCacheVersion = 5; bool LLInventoryModel::sFirstTimeInViewer2 = true; S32 LLInventoryModel::sPendingSystemFolders = 0; +std::vector<std::thread> LLInventoryModel::sPendingCacheThreads; ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs @@ -465,6 +466,7 @@ LLInventoryModel::~LLInventoryModel() void LLInventoryModel::cleanupInventory() { + LL_PROFILE_ZONE_SCOPED; empty(); // Deleting one observer might erase others from the list, so always pop off the front while (!mObservers.empty()) @@ -2367,6 +2369,7 @@ void LLInventoryModel::cache( const LLUUID& parent_folder_id, const LLUUID& agent_id) { + LL_PROFILE_ZONE_SCOPED; LL_DEBUGS(LOG_INV) << "Caching " << parent_folder_id << " for " << agent_id << LL_ENDL; LLViewerInventoryCategory* root_cat = getCategory(parent_folder_id); @@ -2401,18 +2404,57 @@ void LLInventoryModel::cache( } std::string gzip_filename = getInvCacheAddres(agent_id); gzip_filename.append(".gz"); - if(gzip_file(temp_file, gzip_filename)) - { - LL_DEBUGS(LOG_INV) << "Successfully compressed " << temp_file << " to " << gzip_filename << LL_ENDL; - LLFile::remove(temp_file); - } - else + + // Launch detached packing thread + // Main thread is the only one modifying sPendingCacheThreads + sPendingCacheThreads.emplace_back( + [temp_file, gzip_filename]() { + LLTimer gzip_timer; + + if (gzip_file(temp_file, gzip_filename)) + { + F32 gzip_time = gzip_timer.getElapsedTimeF32(); + LL_DEBUGS(LOG_INV) << "Successfully compressed " << temp_file + << " to " << gzip_filename + << " in " << gzip_time << "s (async)" << LL_ENDL; + LLFile::remove(temp_file); + } + else + { + LL_WARNS(LOG_INV) << "Unable to compress " << temp_file + << " into " << gzip_filename << LL_ENDL; + } + }); +} + +void LLInventoryModel::waitForPendingCacheWrites() +{ + LL_PROFILE_ZONE_SCOPED; + + // By this point all threads should have already been added, + // viewer is shutting down, main thread is the only one to + // modify sPendingCacheThreads + if (!sPendingCacheThreads.empty()) { - LL_WARNS(LOG_INV) << "Unable to compress " << temp_file << " into " << gzip_filename << LL_ENDL; + LL_DEBUGS(LOG_INV) << "Waiting for " << sPendingCacheThreads.size() + << " inventory cache compression thread(s) to complete..." << LL_ENDL; + + LLTimer wait_timer; + + for (auto& thread : sPendingCacheThreads) + { + if (thread.joinable()) + { + thread.join(); + } + } + + F32 wait_time = wait_timer.getElapsedTimeF32(); + LL_INFOS(LOG_INV) << "Inventory cache compressions completed in " + << wait_time << "s" << LL_ENDL; } } - void LLInventoryModel::addCategory(LLViewerInventoryCategory* category) { //LL_INFOS(LOG_INV) << "LLInventoryModel::addCategory()" << LL_ENDL; diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 05ada9121a..3a9e3fc3b0 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -195,7 +195,13 @@ public: // Call on logout to save a terse representation. void cache(const LLUUID& parent_folder_id, const LLUUID& agent_id); + + // Wait for any pending async cache operations to complete + static void waitForPendingCacheWrites(); private: + // Async gzip compression tracking + static std::vector<std::thread> sPendingCacheThreads; + // Information for tracking the actual inventory. We index this // information in a lot of different ways so we can access // the inventory using several different identifiers. |
