diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-08-18 12:06:19 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-08-18 12:16:20 +0300 | 
| commit | 6717f4a609e4c158b78069353c0a43fe2fe79af7 (patch) | |
| tree | 440f5a85f1d8aba558c49a10e45997247ef02617 | |
| parent | 48ca2cd67cd8d612ad4101d622dcb18f89e38bfa (diff) | |
SL-17834 MP window freezes when loading items from Inventory #2
| -rw-r--r-- | indra/newview/llmarketplacefunctions.cpp | 34 | 
1 files changed, 21 insertions, 13 deletions
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 74616df079..a5f1622ab2 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -613,22 +613,21 @@ private:      // doesn't hold just marketplace related ids      static std::set<LLUUID> sAddQueue;      static std::set<LLUUID> sStructureQueue; +    static bool sProcessingQueue;  };  std::set<LLUUID> LLMarketplaceInventoryObserver::sAddQueue;  std::set<LLUUID> LLMarketplaceInventoryObserver::sStructureQueue; +bool LLMarketplaceInventoryObserver::sProcessingQueue = false;  void LLMarketplaceInventoryObserver::changed(U32 mask)  { -    bool idle_running = !sAddQueue.empty() && !sStructureQueue.empty(); -    bool needs_idle = false;  	if (mask & LLInventoryObserver::ADD && LLMarketplaceData::instance().hasValidationWaiting())  	{          // When things are added to the marketplace, we might need to re-validate and fix the containing listings          // just add whole list even if it contains items and non-marketplace folders          const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();          sAddQueue.insert(changed_items.begin(), changed_items.end()); -        needs_idle = true;  	}  	if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE)) @@ -640,12 +639,13 @@ void LLMarketplaceInventoryObserver::changed(U32 mask)          // once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied.          const std::set<LLUUID>& changed_items = gInventory.getChangedIDs();          sStructureQueue.insert(changed_items.begin(), changed_items.end()); -        needs_idle = true;  	} -    if (!idle_running && needs_idle) +    if (!sProcessingQueue && (!sAddQueue.empty() || !sStructureQueue.empty()))      {          gIdleCallbacks.addFunction(onIdleProcessQueue, NULL); +        // can do without sProcessingQueue, but it's usufull for simplicity and reliability +        sProcessingQueue = true;      }  } @@ -657,8 +657,13 @@ void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)      if (!sAddQueue.empty())      { -        std::set<LLUUID>::const_iterator id_it = sAddQueue.begin(); -        std::set<LLUUID>::const_iterator id_end = sAddQueue.end(); +        // Make a copy of sAddQueue since decrementValidationWaiting +        // can theoretically add more items +        std::set<LLUUID> add_queue(sAddQueue); +        sAddQueue.clear(); + +        std::set<LLUUID>::const_iterator id_it = add_queue.begin(); +        std::set<LLUUID>::const_iterator id_end = add_queue.end();          // First, count the number of items in this list...          S32 count = 0;          for (; id_it != id_end; ++id_it) @@ -672,7 +677,7 @@ void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)          // Then, decrement the folders of that amount          // Note that of all of those, only one folder will be a listing folder (if at all).          // The other will be ignored by the decrement method. -        id_it = sAddQueue.begin(); +        id_it = add_queue.begin();          for (; id_it != id_end; ++id_it)          {              LLInventoryObject* obj = gInventory.getObject(*id_it); @@ -682,12 +687,11 @@ void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)                  LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(), count);              }          } -        sAddQueue.clear();      } -    std::set<LLUUID>::const_iterator id_it = sStructureQueue.begin(); -    while (id_it != sStructureQueue.end() && LLTimer::getTotalTime() < stop_time) +    while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time)      { +        std::set<LLUUID>::const_iterator id_it = sStructureQueue.begin();          LLInventoryObject* obj = gInventory.getObject(*id_it);          if (obj)          { @@ -713,13 +717,17 @@ void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata)                  }              }          } -        id_it = sStructureQueue.erase(id_it); + +        // sStructureQueue could have been modified in validate_marketplacelistings +        // adding items does not invalidate existing iterator +        sStructureQueue.erase(id_it);      } -    if (LLApp::isExiting() || sStructureQueue.empty()) +    if (LLApp::isExiting() || (sAddQueue.empty() && sStructureQueue.empty()))      {          // Nothing to do anymore          gIdleCallbacks.deleteFunction(onIdleProcessQueue, NULL); +        sProcessingQueue = false;      }  }  | 
