From a3763885d9d787129ddb357953b41178ea7d6509 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Wed, 23 Mar 2022 04:40:11 -0400 Subject: [PATCH] Add support for per-grid cache folders to resolve object cache conflicts --- indra/llfilesystem/lldir.cpp | 36 ++++++++++++---- indra/llfilesystem/lldir.h | 6 ++- indra/llmessage/llexperiencecache.cpp | 18 +------- indra/llmessage/llexperiencecache.h | 4 +- indra/newview/llappviewer.cpp | 59 +++------------------------ indra/newview/llavatariconctrl.cpp | 4 +- indra/newview/llinventorymodel.cpp | 21 +--------- indra/newview/llmutelist.cpp | 22 +++++----- indra/newview/llstartup.cpp | 16 ++++++-- indra/newview/llviewertexturelist.cpp | 2 +- indra/newview/llvocache.cpp | 6 +-- 11 files changed, 72 insertions(+), 122 deletions(-) diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp index fed9c2e5041..1820543b05b 100644 --- a/indra/llfilesystem/lldir.cpp +++ b/indra/llfilesystem/lldir.cpp @@ -375,6 +375,12 @@ const std::string LLDir::getCacheDir(bool get_default) const } } +const std::string LLDir::getCacheDirPerGrid(bool get_default) const +{ + using namespace std::literals; + return add(getCacheDir(get_default), (mGrid.empty() ? "" : "gridcache"), mGrid); +} + // Return the default cache directory std::string LLDir::buildSLOSCacheDir() const { @@ -473,6 +479,7 @@ static std::string ELLPathToString(ELLPath location) ENT(LL_PATH_EXECUTABLE) ENT(LL_PATH_DEFAULT_SKIN) ENT(LL_PATH_FONTS) + ENT(LL_PATH_CACHE_PER_GRID) ENT(LL_PATH_LAST) ; #undef ENT @@ -518,6 +525,10 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd prefix = getCacheDir(); break; + case LL_PATH_CACHE_PER_GRID: + prefix = getCacheDirPerGrid(); + break; + case LL_PATH_DUMP: prefix=getDumpDir(); break; @@ -957,12 +968,12 @@ void LLDir::setChatLogsDir(const std::string &path) void LLDir::updatePerAccountChatLogsDir() { - const std::string& logname = (mGrid.empty()) - ? mUserName : mUserName.append(".").append(mGrid); + const std::string logname = (mGrid.empty()) + ? mUserName : std::string(mUserName).append(".").append(mGrid); mPerAccountChatLogsDir = add(getChatLogsDir(), logname); } -void LLDir::setPerAccountChatLogsDir(const std::string &username, const std::string &gridname) +void LLDir::setPerAccountChatLogsDir(const std::string &username) { // if both first and last aren't set, assume we're grabbing the cached dir if (!username.empty()) @@ -972,12 +983,8 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username, const std::str std::string userlower(username); LLStringUtil::toLower(userlower); LLStringUtil::replaceChar(userlower, ' ', '_'); - std::string gridlower(gridname); - LLStringUtil::toLower(gridlower); - LLStringUtil::replaceChar(gridlower, ' ', '_'); mUserName = userlower; - mGrid = gridlower; updatePerAccountChatLogsDir(); } else @@ -1065,6 +1072,21 @@ bool LLDir::setCacheDir(const std::string &path) } } +void LLDir::setCurrentGrid(std::string gridname) +{ + if (gridname.empty()) + { + mGrid.clear(); + } + else + { + LLStringUtil::toLower(gridname); + LLStringUtil::replaceChar(gridname, ' ', '_'); + + mGrid = gridname; + } +} + void LLDir::dumpCurrentDirectories(LLError::ELevel level) { LL_VLOGS(level, "AppInit","Directories") << "Current Directories:" << LL_ENDL; diff --git a/indra/llfilesystem/lldir.h b/indra/llfilesystem/lldir.h index 9035786e815..c32086ca027 100644 --- a/indra/llfilesystem/lldir.h +++ b/indra/llfilesystem/lldir.h @@ -49,6 +49,7 @@ typedef enum ELLPath LL_PATH_DEFAULT_SKIN = 17, LL_PATH_FONTS = 18, LL_PATH_DUMP = 19, + LL_PATH_CACHE_PER_GRID = 20, LL_PATH_LAST } ELLPath; @@ -94,6 +95,7 @@ class LLDir const std::string &getPerAccountChatLogsDir() const; // Location of the per account chat logs dir. const std::string &getTempDir() const; // Common temporary directory const std::string getCacheDir(bool get_default = false) const; // Location of the cache. + const std::string getCacheDirPerGrid(bool get_default = false) const; // Location of the per-grid cache. const std::string &getOSCacheDir() const; // location of OS-specific cache folder (may be empty string) const std::string &getCAFile() const; // File containing TLS certificate authorities const std::string &getDirDelimiter() const; // directory separator for platform (ie. '\' or '/' or ':') @@ -184,7 +186,7 @@ class LLDir virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir - virtual void setPerAccountChatLogsDir(const std::string &username, const std::string &gridname); // Set the per user chat log directory. + virtual void setPerAccountChatLogsDir(const std::string &username); // Set the per user chat log directory. virtual void setLindenUserDir(const std::string &username, const std::string &gridname); // Set the linden user dir to this user's dir virtual void setSkinFolder(const std::string &skin_folder, const std::string& language); virtual std::string getSkinFolder() const; @@ -223,6 +225,8 @@ class LLDir return destpath; } + void setCurrentGrid(std::string grid); + protected: // Does an add() or append() call need a directory delimiter? typedef std::pair<bool, unsigned short> SepOff; diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp index e9000dbdb40..015e879d765 100644 --- a/indra/llmessage/llexperiencecache.cpp +++ b/indra/llmessage/llexperiencecache.cpp @@ -88,25 +88,9 @@ const int LLExperienceCache::SEARCH_PAGE_SIZE = 30; bool LLExperienceCache::sShutdown = false; //========================================================================= -LLExperienceCache::LLExperienceCache(std::string grid) -{ - std::string file; - if (grid.empty()) - { - file = "experience_cache.xml"; - } - else - { - LLStringUtil::toLower(grid); - LLStringUtil::replaceChar(grid, ' ', '_'); - file = llformat("experience_cache.%s.xml", grid); - } - - mCacheFileName = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, file); -} - void LLExperienceCache::initSingleton() { + mCacheFileName = gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, "experience_cache.xml"); LL_INFOS("ExperienceCache") << "Loading " << mCacheFileName << LL_ENDL; llifstream cache_stream(mCacheFileName.c_str()); diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h index 8f38ac316c6..b1fe4348a7e 100644 --- a/indra/llmessage/llexperiencecache.h +++ b/indra/llmessage/llexperiencecache.h @@ -41,9 +41,9 @@ class LLSD; class LLUUID; -class LLExperienceCache final : public LLParamSingleton < LLExperienceCache > +class LLExperienceCache final : public LLSingleton < LLExperienceCache > { - LLSINGLETON(LLExperienceCache, std::string); + LLSINGLETON_EMPTY_CTOR(LLExperienceCache); public: typedef boost::function<std::string(const std::string &)> CapabilityQuery_t; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3a29a07a97f..35ace70b7a2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4275,8 +4275,6 @@ bool LLAppViewer::initCache() LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); - LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()); - return true; } @@ -4418,6 +4416,7 @@ void LLAppViewer::purgeCache() LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL; LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE); LLVOCache::getInstance()->removeCache(LL_PATH_CACHE); + LLVOCache::getInstance()->removeCache(LL_PATH_CACHE_PER_GRID); std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache"); if (LLFile::isdir(browser_cache)) { @@ -4437,7 +4436,7 @@ void LLAppViewer::purgeCacheImmediate() { LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL; LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false); - LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true); + LLVOCache::getInstance()->removeCache(LL_PATH_CACHE_PER_GRID, true); } std::string LLAppViewer::getSecondLifeTitle() const @@ -4580,19 +4579,8 @@ void LLAppViewer::saveFinalSnapshot() void LLAppViewer::loadNameCache() { // display names cache - std::string file; - if (LLGridManager::getInstance()->isInSecondlife()) - { - file = "avatar_name_cache.xml"; - } - else - { - std::string gridlabel = LLGridManager::getInstance()->getGridId(); - LLStringUtil::toLower(gridlabel); - file = llformat("avatar_name_cache.%s.xml", gridlabel.c_str()); - } std::string filename = - gDirUtilp->getExpandedFilename(LL_PATH_CACHE, file); + gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, "avatar_name_cache.xml"); LL_INFOS("AvNameCache") << filename << LL_ENDL; llifstream name_cache_stream(filename.c_str()); if(name_cache_stream.is_open()) @@ -4607,19 +4595,7 @@ void LLAppViewer::loadNameCache() if (!gCacheName) return; - std::string name_file; - if (LLGridManager::getInstance()->isInSecondlife()) - { - name_file = "name.cache"; - } - else - { - std::string gridid = LLGridManager::getInstance()->getGridId(); - LLStringUtil::toLower(gridid); - name_file = llformat("name.%s.cache", gridid.c_str()); - } - - std::string name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, name_file); + std::string name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, "name.cache"); llifstream cache_file(name_cache.c_str()); if(cache_file.is_open()) { @@ -4630,19 +4606,8 @@ void LLAppViewer::loadNameCache() void LLAppViewer::saveNameCache() { // display names cache - std::string file; - if (LLGridManager::getInstance()->isInSecondlife()) - { - file = "avatar_name_cache.xml"; - } - else - { - std::string gridlabel = LLGridManager::getInstance()->getGridId(); - LLStringUtil::toLower(gridlabel); - file = llformat("avatar_name_cache.%s.xml", gridlabel.c_str()); - } std::string filename = - gDirUtilp->getExpandedFilename(LL_PATH_CACHE, file); + gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, "avatar_name_cache.xml"); llofstream name_cache_stream(filename.c_str()); if(name_cache_stream.is_open()) { @@ -4652,19 +4617,7 @@ void LLAppViewer::saveNameCache() // real names cache if (gCacheName) { - std::string name_file; - if (LLGridManager::getInstance()->isInSecondlife()) - { - name_file = "name.cache"; - } - else - { - std::string gridid = LLGridManager::getInstance()->getGridId(); - LLStringUtil::toLower(gridid); - name_file = llformat("name.%s.cache", gridid.c_str()); - } - - std::string name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, name_file); + std::string name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, "name.cache"); llofstream cache_file(name_cache.c_str()); if(cache_file.is_open()) { diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 46aa6958ff8..ca98600a84a 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -75,7 +75,7 @@ void LLAvatarIconIDCache::load () LL_INFOS() << "Loading avatar icon id cache." << LL_ENDL; // build filename for each user - std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mFilename); + std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, mFilename); llifstream file(resolved_filename.c_str()); if (!file.is_open()) @@ -111,7 +111,7 @@ void LLAvatarIconIDCache::load () void LLAvatarIconIDCache::save () { - std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, mFilename); + std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, mFilename); // open a file for writing llofstream file (resolved_filename.c_str()); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e6a77c8ccbb..dc657821c9a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -81,8 +81,6 @@ BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE; ///---------------------------------------------------------------------------- //BOOL decompress_file(const char* src_filename, const char* dst_filename); -static const char PRODUCTION_CACHE_FORMAT_STRING[] = "%s.inv.llsd"; -static const char GRID_CACHE_FORMAT_STRING[] = "%s.%s.inv.llsd"; static const char * const LOG_INV("Inventory"); struct InventoryIDPtrLess @@ -1896,24 +1894,7 @@ bool LLInventoryModel::fetchDescendentsOf(const LLUUID& folder_id) const //static std::string LLInventoryModel::getInvCacheAddres(const LLUUID& owner_id) { - std::string inventory_addr; - std::string owner_id_str; - owner_id.toString(owner_id_str); - std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str)); - if (LLGridManager::getInstance()->isInSLMain()) - { - inventory_addr = llformat(PRODUCTION_CACHE_FORMAT_STRING, path.c_str()); - } - else - { - // NOTE: The inventory cache filenames now include the grid name. - // Add controls against directory traversal or problematic pathname lengths - // if your viewer uses grid names from an untrusted source. - const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); - const std::string& grid_id_lower = utf8str_tolower(grid_id_str); - inventory_addr = llformat(GRID_CACHE_FORMAT_STRING, path.c_str(), grid_id_lower.c_str()); - } - return inventory_addr; + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, owner_id.asString(), ".inv.llsd"); } void LLInventoryModel::cache( diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index dbf4a3e5130..625f04589f8 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -743,12 +743,16 @@ BOOL LLMuteList::isMuted(const std::string& username, U32 flags) const //----------------------------------------------------------------------------- // requestFromServer() //----------------------------------------------------------------------------- + +std::string get_mutes_cache_file(const LLUUID& agent_id) +{ + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, agent_id.asString()).append(".cached_mute"); + +} + void LLMuteList::requestFromServer(const LLUUID& agent_id) { - std::string agent_id_string; - std::string filename; - agent_id.toString(agent_id_string); - filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute"; + std::string filename = get_mutes_cache_file(agent_id); LLCRC crc; crc.update(filename); @@ -784,10 +788,7 @@ void LLMuteList::cache(const LLUUID& agent_id) // Write to disk even if empty. if(mIsLoaded) { - std::string agent_id_string; - std::string filename; - agent_id.toString(agent_id_string); - filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute"; + std::string filename = get_mutes_cache_file(agent_id); saveToFile(filename); } } @@ -825,10 +826,7 @@ void LLMuteList::processUseCachedMuteList(LLMessageSystem* msg, void**) { LL_INFOS() << "LLMuteList::processUseCachedMuteList()" << LL_ENDL; - std::string agent_id_string; - gAgent.getID().toString(agent_id_string); - std::string filename; - filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,agent_id_string) + ".cached_mute"; + std::string filename = get_mutes_cache_file(gAgent.getID()); LLMuteList::getInstance()->loadFromFile(filename); } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ed87dceece8..b484d9acf55 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -175,6 +175,7 @@ #include "llviewerwindow.h" #include "llvoavatar.h" #include "llvoavatarself.h" +#include "llvocache.h" #include "llweb.h" #include "llworld.h" #include "llworldmapmessage.h" @@ -948,6 +949,12 @@ bool idle_startup() // create necessary directories // *FIX: these mkdir's should error check const std::string& gridlabel = !LLGridManager::getInstance()->isInSecondlife() ? LLGridManager::getInstance()->getGridId() : LLStringUtil::null; + gDirUtilp->setCurrentGrid(gridlabel); + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "gridcache", "")); + LLFile::mkdir(gDirUtilp->getCacheDirPerGrid()); + + LLVOCache::getInstance()->initCache(LL_PATH_CACHE_PER_GRID, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), LLAppViewer::getObjectCacheVersion()); + gDirUtilp->setLindenUserDir(userid, gridlabel); LLFile::mkdir(gDirUtilp->getLindenUserDir()); @@ -996,7 +1003,7 @@ bool idle_startup() { gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath")); } - gDirUtilp->setPerAccountChatLogsDir(userid, gridlabel); + gDirUtilp->setPerAccountChatLogsDir(userid); LLFile::mkdir(gDirUtilp->getChatLogsDir()); LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); @@ -2147,7 +2154,9 @@ bool idle_startup() gAgentWearables.notifyLoadingStarted(); gAgent.setOutfitChosen(TRUE); if (LLGridManager::getInstance()->isInSecondlife()) + { gAgentWearables.sendDummyAgentWearablesUpdate(); + } callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(), set_flags_and_update_appearance); } @@ -2235,6 +2244,9 @@ bool idle_startup() LLStartUp::setStartupState( STATE_CLEANUP ); return TRUE; } + + // Can't fall through here, so return + return TRUE; } //fall through this frame to STATE_CLEANUP } @@ -2935,8 +2947,6 @@ void LLStartUp::initNameCache() void LLStartUp::initExperiences() { // Should trigger loading the cache. - const std::string& gridlabel = !LLGridManager::getInstance()->isInSecondlife() ? LLGridManager::getInstance()->getGridId() : LLStringUtil::null; - LLExperienceCache::initParamSingleton(gridlabel); LLExperienceCache::instance().setCapabilityQuery( boost::bind(&LLAgent::getRegionCapability, &gAgent, _1)); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 34972894831..76cd67c9f25 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -201,7 +201,7 @@ void LLViewerTextureList::doPreloadImages() static std::string get_texture_list_name() { - return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE_PER_GRID, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); } void LLViewerTextureList::doPrefetchImages() diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 628fdb55ec4..c35467a5a0a 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -35,6 +35,7 @@ #include "pipeline.h" #include "llagentcamera.h" #include "llmemory.h" +#include "llviewernetwork.h" //static variables U32 LLVOCacheEntry::sMinFrameRange = 0; @@ -1196,12 +1197,9 @@ void LLVOCache::clearCacheInMemory() void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename) { U32 region_x, region_y; - grid_from_region_handle(handle, ®ion_x, ®ion_y); - filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname, - llformat(OBJECT_CACHE_FILENAME, region_x, region_y)); - return ; + filename = gDirUtilp->add(mObjectCacheDirName, llformat(OBJECT_CACHE_FILENAME, region_x, region_y)); } void LLVOCache::removeFromCache(HeaderEntryInfo* entry) -- GitLab