diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-04-21 00:19:34 +0300 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-04-21 19:18:03 +0300 |
| commit | df5e1c1613798b51fb516c63a52fdbf8b8419fee (patch) | |
| tree | 943eebc920b96fe7e00666af6c21b943da3569a6 /indra | |
| parent | 5cfbf2035e625aa1778d38bbb14ff3d535da81e9 (diff) | |
#5655 Fix freeze on purging cef cache
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/llappviewer.cpp | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ba9fbd7b08..6b8921b09f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4564,13 +4564,66 @@ void LLAppViewer::purgeCefStaleCaches() LL_PROFILE_ZONE_SCOPED; // TODO: we really shouldn't use a hard coded name for the cache folder here... const std::string browser_parent_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); - if (LLFile::isdir(browser_parent_cache)) + if (!LLFile::isdir(browser_parent_cache)) { - // This is a sledgehammer approach - nukes the cef_cache dir entirely - // which is then recreated the first time a CEF instance creates an - // individual cache folder. If we ever decide to retain some folders - // e.g. Search UI cache - then we will need a more granular approach. - gDirUtilp->deleteDirAndContents(browser_parent_cache); + return; + } + // We are using a fixed name to not leave stale folders + // around in case something goes wrong on startup. + const std::string holder_cache_name = browser_parent_cache + "_rename"; + + // Try to rename the entire directory first + if (LLFile::rename(browser_parent_cache, holder_cache_name) == 0) + { + LL_DEBUGS("AppInit") << "Successfully renamed CEF cache folder for deletion" << LL_ENDL; + } + else + { + // Rename failed (likely another instance has files open in the cache) + // Create holder folder and move individual subfolders instead + LL_DEBUGS("AppInit") << "Could not rename CEF cache folder (may be in use), moving individual folders" << LL_ENDL; + + if (!LLFile::isdir(holder_cache_name) && LLFile::mkdir(holder_cache_name) != 0) + { + LL_WARNS() << "Failed to create holder folder: " << holder_cache_name << LL_ENDL; + // Attept normal cleanup + gDirUtilp->deleteDirAndContents(browser_parent_cache); + return; + } + + // Iterate through subdirectories in the cache folder + LLDirIterator dir_iter(browser_parent_cache, "*"); + std::string subfolder_name; + while (dir_iter.next(subfolder_name)) + { + if (subfolder_name == "." || subfolder_name == "..") + { + continue; + } + + std::string source_path = browser_parent_cache + gDirUtilp->getDirDelimiter() + subfolder_name; + std::string dest_path = holder_cache_name + gDirUtilp->getDirDelimiter() + subfolder_name; + + // If folder is in use, move will fail, don't delete it. + LLFile::rename(source_path, dest_path); + } + } + + // Post deletion task to the General work queue to avoid blocking the main thread + if (auto queue = LL::WorkQueue::getInstance("General")) + { + // Alternatively throw it at LLPurgeDiskCacheThread to clean + // it during periodic purges. + queue->post([holder_cache_name]() + { + LL_PROFILE_ZONE_NAMED("cef_cache_cleanup"); + gDirUtilp->deleteDirAndContents(holder_cache_name); + }); + } + else + { + LL_WARNS() << "Failed to get General work queue, deleting CEF cache synchronously" << LL_ENDL; + gDirUtilp->deleteDirAndContents(holder_cache_name); } } |
