diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index a1191e8a31..dc411f8a94 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -1044,6 +1044,27 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht U32 AISUpdate::sBatchFrameCount = 0; LLTimer AISUpdate::sBatchTimer; +// Coalesces the deferred gInventory::notifyObservers() calls issued below +// when the change backlog exceeds MAX_UPDATE_BACKLOG, so repeated iterations +// while the backlog remains large don't flood gMainloopWork with duplicate +// postToMainCoro callbacks. Cleared once the posted callback actually runs +// notifyObservers(). +static bool sAISNotifyObserversPending = false; + +static void aisScheduleNotifyObservers() +{ + if (!sAISNotifyObserversPending) + { + sAISNotifyObserversPending = true; + LLAppViewer::instance()->postToMainCoro( + []() + { + gInventory.notifyObservers(); + sAISNotifyObserversPending = false; + }); + } +} + AISUpdate::AISUpdate(const LLSD& update, AISAPI::COMMAND_TYPE type, const LLSD& request_body) : mType(type) { @@ -1683,7 +1704,7 @@ void AISUpdate::doUpdate() // fetching can receive massive amount of items and folders if (gInventory.getChangedIDs().size() > MAX_UPDATE_BACKLOG) { - gInventory.notifyObservers(); + aisScheduleNotifyObservers(); checkTimeout(); } } @@ -1744,7 +1765,7 @@ void AISUpdate::doUpdate() // fetching can receive massive amount of items and folders if (gInventory.getChangedIDs().size() > MAX_UPDATE_BACKLOG) { - gInventory.notifyObservers(); + aisScheduleNotifyObservers(); checkTimeout(); } } @@ -1815,6 +1836,12 @@ void AISUpdate::doUpdate() checkTimeout(); - gInventory.notifyObservers(); + if (!sAISNotifyObserversPending) + { + LLAppViewer::instance()->postToMainCoro( + []() + { + gInventory.notifyObservers(); + }); + } } - diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c6bfcb5b8e..c141ea3259 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2174,7 +2174,10 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo // Note : We need to tell the inventory observers that those things are going to be deleted *before* the tree is cleared or they won't know what to delete (in views and view models) addChangedMask(LLInventoryObserver::REMOVE, id); - gInventory.notifyObservers(); + if (do_notify_observers) + { + notifyObservers(); + } if (item_array_t* item_list = getUnlockedItemArray(id)) {