diff options
Diffstat (limited to 'indra/newview/llmeshrepository.cpp')
-rwxr-xr-x | indra/newview/llmeshrepository.cpp | 193 |
1 files changed, 176 insertions, 17 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index bc7f522848..09003e3e53 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -204,16 +204,28 @@ 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 (!mProcessed && !LLApp::isQuitting()) + { //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 +241,24 @@ 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 (!mProcessed && !LLApp::isQuitting()) + { + 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 +273,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 +298,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 +323,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 +402,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 +426,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 +468,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 +492,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 +679,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 +714,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 +993,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 +1197,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 +1722,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 +1744,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 +1760,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 +1897,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 +1916,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 +1961,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 +1980,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 +2025,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 +2043,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 +2088,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 +2107,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 +2152,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 +2172,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 +2185,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 +2203,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: " |