From 4cbca3ec8b1e2a40a0c04ca6cb16fa09863e8661 Mon Sep 17 00:00:00 2001 From: Hecklezz Date: Tue, 3 Mar 2026 02:42:06 +1000 Subject: [PATCH] Purge CEF cache in a background thread to help solve long startup times --- indra/llfilesystem/lldir.cpp | 34 ++++++++++++++++ indra/llfilesystem/lldir.h | 1 + indra/newview/llappviewer.cpp | 75 ++++++++++++++++++++++++++++++++++- indra/newview/llappviewer.h | 2 + 4 files changed, 111 insertions(+), 1 deletion(-) diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp index cfdc5d9e9b..7b40549792 100644 --- a/indra/llfilesystem/lldir.cpp +++ b/indra/llfilesystem/lldir.cpp @@ -134,6 +134,40 @@ std::vector LLDir::getFilesInDir(const std::string &dirname) return v; } +// For CEF cache purging in a background thread +std::vector LLDir::getDirectoriesInDir(const std::string &dirname) +{ + //Returns a vector of directory names. + +#ifdef LL_WINDOWS // or BOOST_WINDOWS_API + boost::filesystem::path p(ll_convert(dirname)); +#else + boost::filesystem::path p(dirname); +#endif + + std::vector v; + + boost::system::error_code ec; + if (exists(p, ec) && !ec.failed()) + { + if (is_directory(p, ec) && !ec.failed()) + { + boost::filesystem::directory_iterator end_iter; + for (boost::filesystem::directory_iterator dir_itr(p); + dir_itr != end_iter; + ++dir_itr) + { + if (boost::filesystem::is_directory(dir_itr->status())) + { + v.push_back(dir_itr->path().filename().string()); + } + } + } + } + return v; +} +// + S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) { if (!fileExists(dirname)) return 0; diff --git a/indra/llfilesystem/lldir.h b/indra/llfilesystem/lldir.h index 5c869260f5..ad2da697a1 100644 --- a/indra/llfilesystem/lldir.h +++ b/indra/llfilesystem/lldir.h @@ -78,6 +78,7 @@ class LLDir virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask); U32 deleteDirAndContents(const std::string& dir_name); std::vector getFilesInDir(const std::string &dirname); + std::vector getDirectoriesInDir(const std::string &dirname); // For CEF cache purging in a background thread // pure virtual functions virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index afe8e48c16..fe98ea807c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -689,6 +689,44 @@ public: } }; +// Purge CEF cache in another thread to prevent very slow startup times +class FSCefCachePurgeThread : public LLThread +{ +public: + std::string mCefCachePath; + + FSCefCachePurgeThread(const std::string& cef_cache_path) : LLThread("cef cache purge") + { + mCefCachePath = cef_cache_path; + } + + void run() + { + // Check if the entire cache path can be purged + std::string cef_cache_path_old = mCefCachePath + "_old"; + if (LLFile::isdir(cef_cache_path_old)) + { + gDirUtilp->deleteDirAndContents(cef_cache_path_old); + return; + } + + // Otherwise, purge individual folders that aren't in use + std::vector cef_caches = gDirUtilp->getDirectoriesInDir(mCefCachePath); + for (const auto& cache_dir : cef_caches) + { + if (!LLAppViewer::instance()->isQuitting()) + { + if (cache_dir.ends_with("_old")) + { + std::string cef_cache_path = mCefCachePath + "\\" + cache_dir; + gDirUtilp->deleteDirAndContents(cef_cache_path); + } + } + } + } +}; +// + //virtual bool LLAppViewer::initSLURLHandler() { @@ -740,6 +778,7 @@ LLAppViewer::LLAppViewer() mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", false)), mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", false)), mFastTimerLogThread(NULL), + mCefCachePurgeThread(NULL), // For CEF cache purging in a background thread mSettingsLocationList(NULL), mIsFirstRun(false), mSaveSettingsOnExit(true), // Backup Settings @@ -2481,6 +2520,10 @@ bool LLAppViewer::cleanup() sPurgeDiskCacheThread = NULL; delete mGeneralThreadPool; mGeneralThreadPool = NULL; + // For CEF cache purging in a background thread + delete mCefCachePurgeThread; + mCefCachePurgeThread = NULL; + // if (LLFastTimerView::sAnalyzePerformance) { @@ -5297,7 +5340,10 @@ bool LLAppViewer::initCache() LLVOCache::getInstance()->initCache(LL_PATH_CACHE, CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS, getObjectCacheVersion()); // Remove old, stale CEF cache folders - purgeCefStaleCaches(); + // Purge CEF cache in another thread to prevent very slow startup times + //purgeCefStaleCaches(); + startCefCachePurge(); + // return true; } @@ -5338,6 +5384,33 @@ void LLAppViewer::purgeCefStaleCaches() } } +// Purge CEF cache in another thread to prevent very slow startup times +void LLAppViewer::startCefCachePurge() +{ + const std::string browser_parent_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); + if (LLFile::isdir(browser_parent_cache)) + { + // Try rename the entire cef cache folder to be purged in the background thread + if (LLFile::rename(browser_parent_cache, browser_parent_cache + "_old", -1) == -1) + { + // Otherwise rename the individual cache folders to be purged in the background thread + std::vector cef_caches = gDirUtilp->getDirectoriesInDir(browser_parent_cache); + for (const auto& cache_dir : cef_caches) + { + if (!cache_dir.ends_with("_old")) + { + std::string cef_cache_path = browser_parent_cache + "\\" + cache_dir; + LLFile::rename(cef_cache_path, cef_cache_path + "_old", -1); + } + } + } + + mCefCachePurgeThread = new FSCefCachePurgeThread(browser_parent_cache); + mCefCachePurgeThread->start(); + } +} +// + void LLAppViewer::purgeCache() { LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 5cba00be5a..a123a47553 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -376,6 +376,7 @@ private: // For performance and metric gathering class LLThread* mFastTimerLogThread; + class LLThread* mCefCachePurgeThread; // For CEF cache purging in a background thread // for tracking viewer<->region circuit death bool mAgentRegionLastAlive; @@ -395,6 +396,7 @@ private: // For Windows, purging the cache can take an extraordinary amount of time. Rename the cache dir and purge it using another thread. virtual void startCachePurge() {} + void startCefCachePurge(); // Purge this in another thread to prevent very slow startup times }; // Globals with external linkage. From viewer.h