summaryrefslogtreecommitdiff
path: root/indra/newview/llmeshrepository.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llmeshrepository.cpp')
-rwxr-xr-xindra/newview/llmeshrepository.cpp198
1 files changed, 181 insertions, 17 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index bc7f522848..1223615079 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -204,16 +204,30 @@ class LLMeshHeaderResponder : public LLCurl::Responder
{
public:
LLVolumeParams mMeshParams;
-
+ bool mProcessed;
+
LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
: mMeshParams(mesh_params)
{
- LLMeshRepoThread::sActiveHeaderRequests++;
+ LLMeshRepoThread::incActiveHeaderRequests();
+ mProcessed = false;
}
~LLMeshHeaderResponder()
{
- LLMeshRepoThread::sActiveHeaderRequests--;
+ if (!LLApp::isQuitting())
+ {
+ if (!mProcessed)
+ { //something went wrong, retry
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
+ LLMeshRepository::sHTTPRetryCount++;
+ LLMeshRepoThread::HeaderRequest req(mMeshParams);
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ gMeshRepo.mThread->mHeaderReqQ.push(req);
+ }
+
+ LLMeshRepoThread::decActiveHeaderRequests();
+ }
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -229,16 +243,27 @@ public:
S32 mLOD;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
: mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
{
- LLMeshRepoThread::sActiveLODRequests++;
+ LLMeshRepoThread::incActiveLODRequests();
+ mProcessed = false;
}
~LLMeshLODResponder()
{
- LLMeshRepoThread::sActiveLODRequests--;
+ if (!LLApp::isQuitting())
+ {
+ if (!mProcessed)
+ {
+ llwarns << "Killed without being processed, retrying." << llendl;
+ LLMeshRepository::sHTTPRetryCount++;
+ gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD);
+ }
+ LLMeshRepoThread::decActiveLODRequests();
+ }
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -253,10 +278,17 @@ public:
LLUUID mMeshID;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size)
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
{
+ mProcessed = false;
+ }
+
+ ~LLMeshSkinInfoResponder()
+ {
+ llassert(mProcessed);
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -271,10 +303,17 @@ public:
LLUUID mMeshID;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size)
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
{
+ mProcessed = false;
+ }
+
+ ~LLMeshDecompositionResponder()
+ {
+ llassert(mProcessed);
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -289,10 +328,17 @@ public:
LLUUID mMeshID;
U32 mRequestedBytes;
U32 mOffset;
+ bool mProcessed;
LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size)
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
{
+ mProcessed = false;
+ }
+
+ ~LLMeshPhysicsShapeResponder()
+ {
+ llassert(mProcessed);
}
virtual void completedRaw(U32 status, const std::string& reason,
@@ -361,7 +407,20 @@ public:
mModelData(model_data),
mObserverHandle(observer_handle)
{
+ if (mThread)
+ {
+ mThread->startRequest();
+ }
+ }
+
+ ~LLWholeModelFeeResponder()
+ {
+ if (mThread)
+ {
+ mThread->stopRequest();
+ }
}
+
virtual void completed(U32 status,
const std::string& reason,
const LLSD& content)
@@ -372,7 +431,6 @@ public:
cc = llsd_from_file("fake_upload_error.xml");
}
- mThread->mPendingUploads--;
dump_llsd_to_file(cc,make_dump_name("whole_model_fee_response_",dump_num));
LLWholeModelFeeObserver* observer = mObserverHandle.get();
@@ -415,7 +473,20 @@ public:
mModelData(model_data),
mObserverHandle(observer_handle)
{
+ if (mThread)
+ {
+ mThread->startRequest();
+ }
}
+
+ ~LLWholeModelUploadResponder()
+ {
+ if (mThread)
+ {
+ mThread->stopRequest();
+ }
+ }
+
virtual void completed(U32 status,
const std::string& reason,
const LLSD& content)
@@ -426,7 +497,6 @@ public:
cc = llsd_from_file("fake_upload_error.xml");
}
- mThread->mPendingUploads--;
dump_llsd_to_file(cc,make_dump_name("whole_model_upload_response_",dump_num));
LLWholeModelUploadObserver* observer = mObserverHandle.get();
@@ -614,16 +684,24 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
mPhysicsShapeRequests.insert(mesh_id);
}
+void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+{
+ if (!LLAppViewer::isQuitting())
+ {
+ loadMeshLOD(mesh_params, lod);
+ }
+}
+
-void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
-{ //protected by mSignal, no locking needed here
+void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
+{ //could be called from any thread
+ LLMutexLock lock(mMutex);
mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
if (iter != mMeshHeader.end())
{ //if we have the header, request LOD byte range
LODRequest req(mesh_params, lod);
{
- LLMutexLock lock(mMutex);
mLODReqQ.push(req);
LLMeshRepository::sLODProcessing++;
}
@@ -641,7 +719,6 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
}
else
{ //if no header request is pending, fetch header
- LLMutexLock lock(mMutex);
mHeaderReqQ.push(req);
mPendingLOD[mesh_params].push_back(lod);
}
@@ -921,6 +998,34 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
return ret;
}
+//static
+void LLMeshRepoThread::incActiveLODRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ ++LLMeshRepoThread::sActiveLODRequests;
+}
+
+//static
+void LLMeshRepoThread::decActiveLODRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ --LLMeshRepoThread::sActiveLODRequests;
+}
+
+//static
+void LLMeshRepoThread::incActiveHeaderRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ ++LLMeshRepoThread::sActiveHeaderRequests;
+}
+
+//static
+void LLMeshRepoThread::decActiveHeaderRequests()
+{
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ --LLMeshRepoThread::sActiveHeaderRequests;
+}
+
//return false if failed to get header
bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
{
@@ -1097,11 +1202,13 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
mMeshHeader[mesh_id] = header;
}
+
+ LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time.
+
//check for pending requests
pending_lod_map::iterator iter = mPendingLOD.find(mesh_params);
if (iter != mPendingLOD.end())
{
- LLMutexLock lock(mMutex);
for (U32 i = 0; i < iter->second.size(); ++i)
{
LODRequest req(mesh_params, iter->second[i]);
@@ -1620,7 +1727,7 @@ void LLMeshUploadThread::doWholeModelUpload()
mCurlRequest->process();
//sleep for 10ms to prevent eating a whole core
apr_sleep(10000);
- } while (!LLAppViewer::isQuitting() && mCurlRequest->getQueued() > 0);
+ } while (!LLAppViewer::isQuitting() && mPendingUploads > 0);
}
delete mCurlRequest;
@@ -1642,7 +1749,6 @@ void LLMeshUploadThread::requestWholeModelFee()
wholeModelToLLSD(model_data,false);
dump_llsd_to_file(model_data,make_dump_name("whole_model_fee_request_",dump_num));
- mPendingUploads++;
LLCurlRequest::headers_t headers;
{
@@ -1659,7 +1765,7 @@ void LLMeshUploadThread::requestWholeModelFee()
mCurlRequest->process();
//sleep for 10ms to prevent eating a whole core
apr_sleep(10000);
- } while (!LLApp::isQuitting() && mCurlRequest->getQueued() > 0);
+ } while (!LLApp::isQuitting() && mPendingUploads > 0);
delete mCurlRequest;
mCurlRequest = NULL;
@@ -1796,7 +1902,14 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
-
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1808,11 +1921,13 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD);
}
else
{
+ llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -1851,6 +1966,14 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1862,11 +1985,13 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
}
else
{
+ llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -1905,6 +2030,13 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1916,11 +2048,13 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
}
else
{
+ llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -1959,6 +2093,14 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1970,11 +2112,13 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
{
if (status == 499 || status == 503)
{ //timeout or service unavailable, try again
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
LLMeshRepository::sHTTPRetryCount++;
gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
}
else
{
+ llassert(status == 499 || status == 503); //intentionally trigger a breakpoint
llwarns << "Unhandled status " << status << llendl;
}
return;
@@ -2013,6 +2157,14 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ mProcessed = true;
+
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
if (status < 200 || status > 400)
{
//llwarns
@@ -2025,8 +2177,12 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
// TODO*: Add maximum retry logic, exponential backoff
// and (somewhat more optional than the others) retries
// again after some set period of time
+
+ llassert(status == 503 || status == 499);
+
if (status == 503 || status == 499)
{ //retry
+ llwarns << "Timeout or service unavailable, retrying." << llendl;
LLMeshRepository::sHTTPRetryCount++;
LLMeshRepoThread::HeaderRequest req(mMeshParams);
LLMutexLock lock(gMeshRepo.mThread->mMutex);
@@ -2034,6 +2190,10 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
return;
}
+ else
+ {
+ llwarns << "Unhandled status." << llendl;
+ }
}
S32 data_size = buffer->countAfter(channels.in(), NULL);
@@ -2048,7 +2208,11 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
LLMeshRepository::sBytesReceived += llmin(data_size, 4096);
- if (!gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size))
+ bool success = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
+
+ llassert(success);
+
+ if (!success)
{
llwarns
<< "Unable to parse mesh header: "