diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2020-10-01 22:18:49 +0300 |
---|---|---|
committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2020-10-01 22:36:52 +0300 |
commit | 5172f5d6d6ee76ffe9f7fe0a8a6eb8a86ec93d4d (patch) | |
tree | e3c4e8ccf6cb4fbc6cb57b94c6c04aa105383c10 /indra/newview/llaisapi.cpp | |
parent | 5cae545e09fc805a980cfb040a1c18c3dee5f65a (diff) |
SL-14037 BugSplat Crash #646590: Enqueue failed in AIS
Diffstat (limited to 'indra/newview/llaisapi.cpp')
-rw-r--r-- | indra/newview/llaisapi.cpp | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index ee49125711..005259bcb8 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -44,6 +44,10 @@ const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3"); const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3"); +std::list<AISAPI::ais_query_item_t> AISAPI::sPostponedQuery; + +const S32 MAX_SIMULTANEOUS_COROUTINES = 2048; + //------------------------------------------------------------------------- /*static*/ bool AISAPI::isAvailable() @@ -366,9 +370,51 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t /*static*/ void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc) { + LLCoprocedureManager &inst = LLCoprocedureManager::instance(); + S32 pending_in_pool = inst.countPending("AIS"); std::string procFullName = "AIS(" + procName + ")"; - LLCoprocedureManager::instance().enqueueCoprocedure("AIS", procFullName, proc); + if (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES) + { + inst.enqueueCoprocedure("AIS", procFullName, proc); + } + else + { + // As I understand it, coroutines have built-in 'pending' pool + // but unfortunately it has limited size which inventory often goes over + // so this is a workaround to not overfill it. + if (sPostponedQuery.empty()) + { + sPostponedQuery.push_back(ais_query_item_t(procFullName, proc)); + gIdleCallbacks.addFunction(onIdle, NULL); + } + else + { + sPostponedQuery.push_back(ais_query_item_t(procFullName, proc)); + } + } +} +/*static*/ +void AISAPI::onIdle(void *userdata) +{ + if (!sPostponedQuery.empty()) + { + LLCoprocedureManager &inst = LLCoprocedureManager::instance(); + S32 pending_in_pool = inst.countPending("AIS"); + while (pending_in_pool < MAX_SIMULTANEOUS_COROUTINES && !sPostponedQuery.empty()) + { + ais_query_item_t &item = sPostponedQuery.front(); + inst.enqueueCoprocedure("AIS", item.first, item.second); + sPostponedQuery.pop_front(); + pending_in_pool++; + } + } + + if (sPostponedQuery.empty()) + { + // Nothing to do anymore + gIdleCallbacks.deleteFunction(onIdle, NULL); + } } /*static*/ |