summaryrefslogtreecommitdiff
path: root/indra/newview/lllandmarklist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lllandmarklist.cpp')
-rw-r--r--indra/newview/lllandmarklist.cpp53
1 files changed, 52 insertions, 1 deletions
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index c58540914e..543d2a087f 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -39,6 +39,11 @@
// Globals
LLLandmarkList gLandmarkList;
+// number is mostly arbitrary, but it should be below DEFAULT_QUEUE_SIZE pool size,
+// which is 4096, to not overfill the pool if user has more than 4K of landmarks
+// and it should leave some space for other potential simultaneous asset request
+const S32 MAX_SIMULTANEOUS_REQUESTS = 512;
+
////////////////////////////////////////////////////////////////////////////
// LLLandmarkList
@@ -69,6 +74,11 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
{
return NULL;
}
+ if ( mWaitList.find(asset_uuid) != mWaitList.end() )
+ {
+ // Landmark is sheduled for download, but not requested yet
+ return NULL;
+ }
landmark_requested_list_t::iterator iter = mRequestedList.find(asset_uuid);
if (iter != mRequestedList.end())
@@ -86,11 +96,24 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
mLoadedCallbackMap.insert(vt);
}
+ if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
+ {
+ // Workarounds for corutines pending list size limit:
+ // Postpone download till queue is emptier.
+ // Coroutines have own built in 'pending' list, but unfortunately
+ // it is too small compared to potential amount of landmarks
+ // or assets.
+ mWaitList.insert(asset_uuid);
+ return NULL;
+ }
+
+ mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+ // Note that getAssetData can callback immediately and cleans mRequestedList
gAssetStorage->getAssetData(asset_uuid,
LLAssetType::AT_LANDMARK,
LLLandmarkList::processGetAssetReply,
NULL);
- mRequestedList[asset_uuid] = gFrameTimeSeconds;
}
return NULL;
}
@@ -155,8 +178,36 @@ void LLLandmarkList::processGetAssetReply(
}
gLandmarkList.mBadList.insert(uuid);
+ gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests
+ // todo: this should clean mLoadedCallbackMap!
}
+ // getAssetData can fire callback immediately, causing
+ // a recursion which is suboptimal for very large wait list.
+ // 'scheduling' indicates that we are inside request and
+ // shouldn't be launching more requests.
+ static bool scheduling = false;
+ if (!scheduling && !gLandmarkList.mWaitList.empty())
+ {
+ scheduling = true;
+ while (!gLandmarkList.mWaitList.empty() && gLandmarkList.mRequestedList.size() < MAX_SIMULTANEOUS_REQUESTS)
+ {
+ // start new download from wait list
+ landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
+ LLUUID asset_uuid = *iter;
+ gLandmarkList.mWaitList.erase(iter);
+
+ // add to mRequestedList before calling getAssetData()
+ gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+ // Note that getAssetData can callback immediately and cleans mRequestedList
+ gAssetStorage->getAssetData(asset_uuid,
+ LLAssetType::AT_LANDMARK,
+ LLLandmarkList::processGetAssetReply,
+ NULL);
+ }
+ scheduling = false;
+ }
}
BOOL LLLandmarkList::isAssetInLoadedCallbackMap(const LLUUID& asset_uuid)