diff --git a/indra/llcommon/llversionviewer.h.in b/indra/llcommon/llversionviewer.h.in index e1fa1cab3..efe9ad7aa 100644 --- a/indra/llcommon/llversionviewer.h.in +++ b/indra/llcommon/llversionviewer.h.in @@ -35,7 +35,7 @@ const S32 LL_VERSION_MAJOR = 1; const S32 LL_VERSION_MINOR = 8; -const S32 LL_VERSION_PATCH = 0; +const S32 LL_VERSION_PATCH = 1; const S32 LL_VERSION_BUILD = ${vBUILD}; const char * const LL_CHANNEL = "${VIEWER_CHANNEL}"; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 17b3f70e1..66ed09f26 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -213,16 +213,30 @@ class LLMeshHeaderResponder : public LLHTTPClient::ResponderWithCompleted { 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, @@ -241,16 +255,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, @@ -268,10 +293,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, @@ -289,10 +321,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, @@ -310,10 +349,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, @@ -680,16 +726,22 @@ 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 - +{ //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++; } @@ -707,7 +759,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); } @@ -961,6 +1012,34 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) return true; } +//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) { @@ -1776,7 +1855,8 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - + mProcessed = true; + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -1788,6 +1868,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, { if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD); } @@ -1831,6 +1912,8 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + mProcessed = true; + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -1842,6 +1925,7 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason { if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshSkinInfo(mMeshID); } @@ -1885,6 +1969,8 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + mProcessed = true; + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -1896,6 +1982,7 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r { if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshDecomposition(mMeshID); } @@ -1939,6 +2026,8 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + mProcessed = true; + S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status >= 400) @@ -1950,6 +2039,7 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re { if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //timeout or service unavailable, try again + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID); } @@ -1993,6 +2083,8 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { + mProcessed = true; + if (status < 200 || status >= 400) { //llwarns @@ -2007,6 +2099,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, // again after some set period of time if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE) { //retry + llwarns << "Timeout or service unavailable, retrying." << llendl; LLMeshRepository::sHTTPRetryCount++; LLMeshRepoThread::HeaderRequest req(mMeshParams); LLMutexLock lock(gMeshRepo.mThread->mMutex); @@ -2014,6 +2107,10 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, return; } + else + { + llwarns << "Unhandled status." << llendl; + } } S32 data_size = buffer->countAfter(channels.in(), NULL); @@ -2028,7 +2125,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: " diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 5f397c206..4b535f397 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -321,6 +321,7 @@ public: virtual void run(); + void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count); void fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count); @@ -350,6 +351,10 @@ public: // (should hold onto mesh_id and try again later if header info does not exist) bool fetchMeshPhysicsShape(const LLUUID& mesh_id); + static void incActiveLODRequests(); + static void decActiveLODRequests(); + static void incActiveHeaderRequests(); + static void decActiveHeaderRequests(); };