summaryrefslogtreecommitdiff
path: root/indra/llmessage/llcoproceduremanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/llcoproceduremanager.cpp')
-rw-r--r--indra/llmessage/llcoproceduremanager.cpp69
1 files changed, 56 insertions, 13 deletions
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index 263670bdac..0e5725baf3 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -50,17 +50,21 @@ static const U32 DEFAULT_POOL_SIZE = 5;
// SL-14399: When we teleport to a brand-new simulator, the coprocedure queue
// gets absolutely slammed with fetch requests. Make this queue effectively
// unlimited.
-const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*1024;
+const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*512;
//=========================================================================
-class LLCoprocedurePool: private boost::noncopyable
+class LLCoprocedurePool
{
public:
typedef LLCoprocedureManager::CoProcedure_t CoProcedure_t;
- LLCoprocedurePool(const std::string &name, size_t size);
+ LLCoprocedurePool(const std::string &name, size_t size, size_t queue_size);
~LLCoprocedurePool();
+ // Non-copyable
+ LLCoprocedurePool(const LLCoprocedurePool&) = delete;
+ LLCoprocedurePool& operator=(const LLCoprocedurePool&) = delete;
+
/// Places the coprocedure on the queue for processing.
///
/// @param name Is used for debugging and should identify this coroutine.
@@ -118,7 +122,7 @@ private:
typedef std::shared_ptr<CoprocQueue_t> CoprocQueuePtr;
std::string mPoolName;
- size_t mPoolSize, mActiveCoprocsCount, mPending;
+ size_t mPoolSize, mQueueSize, mActiveCoprocsCount, mPending;
CoprocQueuePtr mPendingCoprocs;
LLTempBoundListener mStatusListener;
@@ -138,10 +142,25 @@ LLCoprocedureManager::LLCoprocedureManager()
LLCoprocedureManager::~LLCoprocedureManager()
{
- close();
+ try
+ {
+ close();
+ }
+ catch (const boost::fibers::fiber_error&)
+ {
+ LL_WARNS() << "Fiber error during ~LLCoprocedureManager()" << LL_ENDL;
+ }
+ catch (const std::exception& e)
+ {
+ // Shutting down, just log it
+ LL_WARNS() << "Exception during ~LLCoprocedureManager(): " << e.what() << LL_ENDL;
+ }
+ mPropertyQueryFn = nullptr;
+ mPropertyDefineFn = nullptr;
+ mPoolMap.clear();
}
-void LLCoprocedureManager::initializePool(const std::string &poolName)
+void LLCoprocedureManager::initializePool(const std::string &poolName, size_t queue_size)
{
poolMap_t::iterator it = mPoolMap.find(poolName);
@@ -180,7 +199,7 @@ void LLCoprocedureManager::initializePool(const std::string &poolName)
LL_WARNS("CoProcMgr") << "LLCoprocedureManager: No setting for \"" << keyName << "\" setting pool size to default of " << size << LL_ENDL;
}
- poolPtr_t pool(new LLCoprocedurePool(poolName, size));
+ poolPtr_t pool = std::make_shared<LLCoprocedurePool>(poolName, size, queue_size);
LL_ERRS_IF(!pool, "CoprocedureManager") << "Unable to create pool named \"" << poolName << "\" FATAL!" << LL_ENDL;
bool inserted = mPoolMap.emplace(poolName, pool).second;
@@ -212,7 +231,8 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd
mPropertyQueryFn = queryfn;
mPropertyDefineFn = updatefn;
- initializePool("Upload");
+ constexpr size_t UPLOAD_QUEUE_SIZE = 2048;
+ initializePool("Upload", UPLOAD_QUEUE_SIZE);
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
@@ -296,17 +316,19 @@ void LLCoprocedureManager::close(const std::string &pool)
}
//=========================================================================
-LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
+LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size, size_t queue_size):
mPoolName(poolName),
mPoolSize(size),
+ mQueueSize(queue_size),
mActiveCoprocsCount(0),
mPending(0),
- mPendingCoprocs(std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)),
mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mCoroMapping()
{
+ llassert_always(mQueueSize > mPoolSize); // queue should be able to fit pool
try
{
+ mPendingCoprocs = std::make_shared<CoprocQueue_t>(mQueueSize);
// store in our LLTempBoundListener so that when the LLCoprocedurePool is
// destroyed, we implicitly disconnect from this LLEventPump
// Monitores application status
@@ -339,10 +361,15 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
llassert(0); // Fix Me! Ignoring missing listener!
}
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("CoProcMgr") << "Bad memory allocation in LLCoprocedurePool::LLCoprocedurePool!" << LL_ENDL;
+ }
for (size_t count = 0; count < mPoolSize; ++count)
{
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter( mPoolName + "Adapter", mHTTPPolicy));
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter = std::make_shared<LLCoreHttpUtil::HttpCoroutineAdapter>(mPoolName + "Adapter", mHTTPPolicy);
std::string pooledCoro = LLCoros::instance().launch(
"LLCoprocedurePool("+mPoolName+")::coprocedureInvokerCoro",
@@ -352,11 +379,27 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter));
}
- LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL;
+ LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << mQueueSize << LL_ENDL;
}
LLCoprocedurePool::~LLCoprocedurePool()
{
+ try
+ {
+ close(); // should have been closed already, but shouldn't hurt
+ mStatusListener.disconnect();
+ mPendingCoprocs.reset();
+ mCoroMapping.clear();
+ }
+ catch (const boost::fibers::fiber_error&)
+ {
+ LL_WARNS() << "Fiber error during ~LLCoprocedurePool() " << mPoolName << LL_ENDL;
+ }
+ catch (const std::exception& e)
+ {
+ // Shutting down, just log it
+ LL_WARNS() << "Exception " << e.what() << " during ~LLCoprocedurePool() in " << mPoolName << LL_ENDL;
+ }
}
//-------------------------------------------------------------------------
@@ -371,7 +414,7 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced
<< "\" at "
<< mPending << LL_ENDL;
- if (mPending >= (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1))
+ if (mPending >= (mQueueSize - 1))
{
// If it's all used up (not supposed to happen,
// fetched should cap it), we are going to crash