From 24d4517458f46ad0cd7284a5f30c4d961d518aa8 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Wed, 10 Feb 2021 01:10:36 +0200
Subject: [PATCH] SL-14807 Viewer crashes when creating an experience

---
 indra/llmessage/llcoproceduremanager.cpp | 18 ++++++++++++------
 indra/llmessage/llcoproceduremanager.h   |  4 ++--
 indra/llmessage/llexperiencecache.cpp    |  2 ++
 indra/newview/llstartup.cpp              |  3 ---
 indra/newview/llviewerassetstorage.cpp   |  1 +
 5 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index a4fe3a2a8e1..850d4da74f1 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -138,7 +138,7 @@ LLCoprocedureManager::~LLCoprocedureManager()
     close();
 }
 
-LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::string &poolName)
+void LLCoprocedureManager::initializePool(const std::string &poolName)
 {
     // Attempt to look up a pool size in the configuration.  If found use that
     std::string keyName = "PoolSize" + poolName;
@@ -171,8 +171,6 @@ LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::
 
     bool inserted = mPoolMap.emplace(poolName, pool).second;
     LL_ERRS_IF(!inserted, "CoprocedureManager") << "Unable to add pool named \"" << poolName << "\" to map. FATAL!" << LL_ENDL;
-
-    return pool;
 }
 
 //-------------------------------------------------------------------------
@@ -182,20 +180,28 @@ LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const s
     // not exist, create it.
     poolMap_t::iterator it = mPoolMap.find(pool);
 
-    poolPtr_t targetPool = (it != mPoolMap.end()) ? it->second : initializePool(pool);
+    if (it == mPoolMap.end())
+    {
+        // initializing pools in enqueueCoprocedure is not thread safe,
+        // at the moment pools need to be initialized manually
+        LL_ERRS() << "Uninitialized pool " << name << LL_ENDL;
+    }
 
+    poolPtr_t targetPool = it->second;
     return targetPool->enqueueCoprocedure(name, proc);
 }
 
 void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn)
 {
     // functions to discover and store the pool sizes
+    // Might be a better idea to make an initializePool(name, size) to init everything externally
     mPropertyQueryFn = queryfn;
     mPropertyDefineFn = updatefn;
 
-    // workaround until we get mutex into initializePool
-    initializePool("VAssetStorage");
     initializePool("Upload");
+    initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS
+    // "ExpCache" pool gets initialized in LLExperienceCache
+    // asset storage pool gets initialized in LLViewerAssetStorage
 }
 
 //-------------------------------------------------------------------------
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 70204ba02b5..d6973996a95 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -79,6 +79,8 @@ class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
 
     void close();
     void close(const std::string &pool);
+
+    void initializePool(const std::string &poolName);
     
 private:
 
@@ -87,8 +89,6 @@ class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
 
     poolMap_t mPoolMap;
 
-    poolPtr_t initializePool(const std::string &poolName);
-
     SettingQuery_t mPropertyQueryFn;
     SettingUpdate_t mPropertyDefineFn;
 };
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 64c01bd9ebd..db22ad2ea36 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -108,6 +108,8 @@ void LLExperienceCache::initSingleton()
         cache_stream >> (*this);
     }
 
+    LLCoprocedureManager::instance().initializePool("ExpCache");
+
     LLCoros::instance().launch("LLExperienceCache::idleCoro",
         boost::bind(&LLExperienceCache::idleCoro, this));
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 17777c3cebd..e4a5687dc63 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1818,9 +1818,6 @@ bool idle_startup()
 		
 		display_startup();
 
-		//all categories loaded. lets create "My Favorites" category
-		gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
-
 		// set up callbacks
 		LL_INFOS() << "Registering Callbacks" << LL_ENDL;
 		LLMessageSystem* msg = gMessageSystem;
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 54f80a29952..b345396c2f1 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -128,6 +128,7 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *
       mCountSucceeded(0),
       mTotalBytesFetched(0)
 {
+    LLCoprocedureManager::instance().initializePool(VIEWER_ASSET_STORAGE_CORO_POOL);
 }
 
 LLViewerAssetStorage::~LLViewerAssetStorage()
-- 
GitLab