summaryrefslogtreecommitdiff
path: root/indra/newview/llaisapi.cpp
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-10-01 22:18:49 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-10-01 22:36:52 +0300
commit5172f5d6d6ee76ffe9f7fe0a8a6eb8a86ec93d4d (patch)
treee3c4e8ccf6cb4fbc6cb57b94c6c04aa105383c10 /indra/newview/llaisapi.cpp
parent5cae545e09fc805a980cfb040a1c18c3dee5f65a (diff)
SL-14037 BugSplat Crash #646590: Enqueue failed in AIS
Diffstat (limited to 'indra/newview/llaisapi.cpp')
-rw-r--r--indra/newview/llaisapi.cpp48
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*/