summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRye Mutt <rye@alchemyviewer.org>2022-09-27 17:35:23 -0400
committerRye Mutt <rye@alchemyviewer.org>2022-09-27 17:59:21 -0400
commit9ec86c84e3d75feb5505a98e96db542b054e162e (patch)
tree3969267827ea458b038ea1cda7ed7f410b837fb4
parentbd20b61b8261623d75bbb22e7d368743d7bd971a (diff)
Add proper retry support to skin info fetch
-rw-r--r--indra/newview/llmeshrepository.cpp115
-rw-r--r--indra/newview/llmeshrepository.h9
2 files changed, 83 insertions, 41 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index ed942eca31..53ce952739 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -857,6 +857,12 @@ LLMeshRepoThread::~LLMeshRepoThread()
mHttpRequestSet.clear();
mHttpHeaders.reset();
+ while (!mSkinInfoQ.empty())
+ {
+ delete mSkinInfoQ.front();
+ mSkinInfoQ.pop_front();
+ }
+
while (!mDecompositionQ.empty())
{
delete mDecompositionQ.front();
@@ -946,6 +952,7 @@ void LLMeshRepoThread::run()
else
{
// too many fails
+ LLMutexLock lock(mMutex);
mUnavailableQ.push(req);
LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL;
}
@@ -1022,37 +1029,42 @@ void LLMeshRepoThread::run()
if (!mSkinRequests.empty())
{
- std::set<UUIDBasedRequest> incomplete;
- while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
- mMutex->lock();
- std::set<UUIDBasedRequest>::iterator iter = mSkinRequests.begin();
- UUIDBasedRequest req = *iter;
- mSkinRequests.erase(iter);
- mMutex->unlock();
- if (req.isDelayed())
- {
- incomplete.insert(req);
- }
- else if (!fetchMeshSkinInfo(req.mId))
- {
- if (req.canRetry())
- {
- req.updateTime();
- incomplete.insert(req);
- }
- else
- {
- LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL;
- }
- }
- }
+ std::list<UUIDBasedRequest> incomplete;
+ while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
- if (!incomplete.empty())
- {
- LLMutexLock locker(mMutex);
- mSkinRequests.insert(incomplete.begin(), incomplete.end());
- }
+ mMutex->lock();
+ auto req = mSkinRequests.front();
+ mSkinRequests.pop_front();
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ incomplete.emplace_back(req);
+ }
+ else if (!fetchMeshSkinInfo(req.mId, req.canRetry()))
+ {
+ if (req.canRetry())
+ {
+ req.updateTime();
+ incomplete.emplace_back(req);
+ }
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.push_back(req);
+ LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL;
+ }
+ }
+ }
+
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ for (const auto& req : incomplete)
+ {
+ mSkinRequests.push_back(req);
+ }
+ }
}
// holding lock, try next list
@@ -1151,7 +1163,7 @@ void LLMeshRepoThread::run()
// Mutex: LLMeshRepoThread::mMutex must be held on entry
void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id)
{
- mSkinRequests.insert(UUIDBasedRequest(mesh_id));
+ mSkinRequests.push_back(UUIDBasedRequest(mesh_id));
}
// Mutex: LLMeshRepoThread::mMutex must be held on entry
@@ -1308,7 +1320,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
}
-bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
+bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)
{
if (!mHeaderMutex)
@@ -1390,13 +1402,28 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
<< LL_ENDL;
ret = false;
}
- else
+ else if(can_retry)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
}
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.emplace_back(mesh_id);
+ }
+ }
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.emplace_back(mesh_id);
}
}
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.emplace_back(mesh_id);
+ }
}
else
{
@@ -2906,13 +2933,20 @@ void LLMeshRepoThread::notifyLoadedMeshes()
{
if (mMutex->trylock())
{
- std::list<LLMeshSkinInfo*> skin_info_q;
+ std::deque<LLMeshSkinInfo*> skin_info_q;
+ std::deque<UUIDBasedRequest> skin_info_unavail_q;
std::list<LLModel::Decomposition*> decomp_q;
if (! mSkinInfoQ.empty())
{
skin_info_q.swap(mSkinInfoQ);
}
+
+ if (! mSkinUnavailableQ.empty())
+ {
+ skin_info_unavail_q.swap(mSkinUnavailableQ);
+ }
+
if (! mDecompositionQ.empty())
{
decomp_q.swap(mDecompositionQ);
@@ -2926,6 +2960,11 @@ void LLMeshRepoThread::notifyLoadedMeshes()
gMeshRepo.notifySkinInfoReceived(skin_info_q.front());
skin_info_q.pop_front();
}
+ while (! skin_info_unavail_q.empty())
+ {
+ gMeshRepo.notifySkinInfoUnavailable(skin_info_unavail_q.front().mId);
+ skin_info_unavail_q.pop_front();
+ }
while (! decomp_q.empty())
{
@@ -3357,9 +3396,8 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status)
<< ", Reason: " << status.toString()
<< " (" << status.toTerseString() << "). Not retrying."
<< LL_ENDL;
-
- // *TODO: Mark mesh unavailable on error. For now, simply leave
- // request unfulfilled rather than retry forever.
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID);
}
void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
@@ -3390,7 +3428,8 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /*
LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID
<< ", Unknown reason. Not retrying."
<< LL_ENDL;
- // *TODO: Mark mesh unavailable on error
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID);
}
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 01a8427757..f62216d8ba 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -281,10 +281,13 @@ public:
};
//set of requested skin info
- std::set<UUIDBasedRequest> mSkinRequests;
+ std::deque<UUIDBasedRequest> mSkinRequests;
// list of completed skin info requests
- std::list<LLMeshSkinInfo*> mSkinInfoQ;
+ std::deque<LLMeshSkinInfo*> mSkinInfoQ;
+
+ // list of skin info requests that have failed or are unavailaibe
+ std::deque<UUIDBasedRequest> mSkinUnavailableQ;
//set of requested decompositions
std::set<UUIDBasedRequest> mDecompositionRequests;
@@ -352,7 +355,7 @@ public:
//send request for skin info, returns true if header info exists
// (should hold onto mesh_id and try again later if header info does not exist)
- bool fetchMeshSkinInfo(const LLUUID& mesh_id);
+ bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true);
//send request for decomposition, returns true if header info exists
// (should hold onto mesh_id and try again later if header info does not exist)