From 9e621af3db9fbb0728bf7b338ea4e17c56ab25bb Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 24 Jan 2012 17:37:20 -0600 Subject: SH-2791 Use request class constructor/destructor for keeping track of concurrent requests instead of unreliable increments/decrements sprinkled around the code. --- indra/newview/llmeshrepository.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'indra/newview/llmeshrepository.cpp') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1d0c262190..03dc7f6bba 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -208,6 +208,12 @@ public: LLMeshHeaderResponder(const LLVolumeParams& mesh_params) : mMeshParams(mesh_params) { + LLMeshRepoThread::sActiveHeaderRequests++; + } + + ~LLMeshHeaderResponder() + { + LLMeshRepoThread::sActiveHeaderRequests--; } virtual void completedRaw(U32 status, const std::string& reason, @@ -227,6 +233,12 @@ public: LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes) : mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes) { + LLMeshRepoThread::sActiveLODRequests++; + } + + ~LLMeshLODResponder() + { + LLMeshRepoThread::sActiveLODRequests--; } virtual void completedRaw(U32 status, const std::string& reason, @@ -710,7 +722,6 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - ++sActiveLODRequests; LLMeshRepository::sHTTPRequestCount++; mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size, new LLMeshSkinInfoResponder(mesh_id, offset, size)); @@ -783,7 +794,6 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - ++sActiveLODRequests; LLMeshRepository::sHTTPRequestCount++; mCurlRequest->getByteRange(http_url, headers, offset, size, new LLMeshDecompositionResponder(mesh_id, offset, size)); @@ -856,7 +866,6 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - ++sActiveLODRequests; LLMeshRepository::sHTTPRequestCount++; mCurlRequest->getByteRange(http_url, headers, offset, size, new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); @@ -907,7 +916,6 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) std::string http_url = constructUrl(mesh_params.getSculptID()); if (!http_url.empty()) { - ++sActiveHeaderRequests; retval = true; //grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits //within the first 4KB @@ -974,7 +982,6 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) std::string http_url = constructUrl(mesh_id); if (!http_url.empty()) { - ++sActiveLODRequests; retval = true; LLMeshRepository::sHTTPRequestCount++; mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size, @@ -1718,7 +1725,6 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, const LLIOPipe::buffer_ptr_t& buffer) { - LLMeshRepoThread::sActiveLODRequests--; S32 data_size = buffer->countAfter(channels.in(), NULL); if (status < 200 || status > 400) @@ -1935,7 +1941,6 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - LLMeshRepoThread::sActiveHeaderRequests--; if (status < 200 || status > 400) { //llwarns -- cgit v1.2.3 From 127f6d14050bd1d10b3a4b4b8a4c315da43e9f92 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Tue, 31 Jan 2012 16:36:25 -0800 Subject: Fixed up LLVolume memory leak caused by mesh repo thread. Reviewed by Bao. --- indra/newview/llmeshrepository.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'indra/newview/llmeshrepository.cpp') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 03dc7f6bba..f2a24bf18a 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1068,17 +1068,19 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size) { - LLVolume* volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); + LLPointer volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); std::string mesh_string((char*) data, data_size); std::istringstream stream(mesh_string); if (volume->unpackVolumeFaces(stream, data_size)) { - LoadedMesh mesh(volume, mesh_params, lod); if (volume->getNumFaces() > 0) { - LLMutexLock lock(mMutex); - mLoadedQ.push(mesh); + LoadedMesh mesh(volume, mesh_params, lod); + { + LLMutexLock lock(mMutex); + mLoadedQ.push(mesh); + } return true; } } -- cgit v1.2.3 From 6ecae04d358cc27bc4890778a1493b3818236fb9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 17 Feb 2012 15:33:09 -0600 Subject: SH-2941 Fix for crash on shutdown due to race condition between LLCurl and LLMeshRepository --- indra/newview/llmeshrepository.cpp | 288 +++++++++++++++---------------------- 1 file changed, 118 insertions(+), 170 deletions(-) (limited to 'indra/newview/llmeshrepository.cpp') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index bd20210190..f461c7e46f 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -508,6 +508,7 @@ void LLMeshRepoThread::run() while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveLODRequests < sMaxConcurrentRequests) { + if (mMutex) { mMutex->lock(); LODRequest req = mLODReqQ.front(); @@ -525,6 +526,7 @@ void LLMeshRepoThread::run() while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveHeaderRequests < sMaxConcurrentRequests) { + if (mMutex) { mMutex->lock(); HeaderRequest req = mHeaderReqQ.front(); @@ -671,6 +673,12 @@ std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id) bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) { //protected by mMutex + + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) @@ -747,6 +755,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) @@ -824,6 +837,11 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) @@ -950,6 +968,11 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& c //return false if failed to get mesh lod. bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count) { //protected by mMutex + if (!mHeaderMutex) + { + return false; + } + mHeaderMutex->lock(); bool retval = true; @@ -1068,10 +1091,11 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat { LLUUID mesh_id = mesh_params.getSculptID(); - mHeaderMutex->lock(); - mMeshHeaderSize[mesh_id] = header_size; - mMeshHeader[mesh_id] = header; - mHeaderMutex->unlock(); + { + LLMutexLock lock(mHeaderMutex); + mMeshHeaderSize[mesh_id] = header_size; + mMeshHeader[mesh_id] = header; + } //check for pending requests pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); @@ -1646,6 +1670,11 @@ void LLMeshUploadThread::requestWholeModelFee() void LLMeshRepoThread::notifyLoadedMeshes() { + if (!mMutex) + { + return; + } + while (!mLoadedQ.empty()) { mMutex->lock(); @@ -2357,93 +2386,92 @@ void LLMeshRepository::notifyLoadedMeshes() } } - mMeshMutex->lock(); - mThread->mMutex->lock(); - - //popup queued error messages from background threads - while (!mUploadErrorQ.empty()) { - LLNotificationsUtil::add("MeshUploadError", mUploadErrorQ.front()); - mUploadErrorQ.pop(); - } + LLMutexLock lock1(mMeshMutex); + LLMutexLock lock2(mThread->mMutex); + + //popup queued error messages from background threads + while (!mUploadErrorQ.empty()) + { + LLNotificationsUtil::add("MeshUploadError", mUploadErrorQ.front()); + mUploadErrorQ.pop(); + } - S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests); + S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests); - if (push_count > 0) - { - //calculate "score" for pending requests + if (push_count > 0) + { + //calculate "score" for pending requests - //create score map - std::map score_map; + //create score map + std::map score_map; - for (U32 i = 0; i < 4; ++i) - { - for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) + for (U32 i = 0; i < 4; ++i) { - F32 max_score = 0.f; - for (std::set::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { - LLViewerObject* object = gObjectList.findObject(*obj_iter); - - if (object) + F32 max_score = 0.f; + for (std::set::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { - LLDrawable* drawable = object->mDrawable; - if (drawable) + LLViewerObject* object = gObjectList.findObject(*obj_iter); + + if (object) { - F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); - max_score = llmax(max_score, cur_score); + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); + max_score = llmax(max_score, cur_score); + } } } - } - score_map[iter->first.getSculptID()] = max_score; + score_map[iter->first.getSculptID()] = max_score; + } + } + + //set "score" for pending requests + for (std::vector::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) + { + iter->mScore = score_map[iter->mMeshParams.getSculptID()]; + } + + //sort by "score" + std::sort(mPendingRequests.begin(), mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater()); + + while (!mPendingRequests.empty() && push_count > 0) + { + LLMeshRepoThread::LODRequest& request = mPendingRequests.front(); + mThread->loadMeshLOD(request.mMeshParams, request.mLOD); + mPendingRequests.erase(mPendingRequests.begin()); + LLMeshRepository::sLODPending--; + push_count--; } } - //set "score" for pending requests - for (std::vector::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) + //send skin info requests + while (!mPendingSkinRequests.empty()) { - iter->mScore = score_map[iter->mMeshParams.getSculptID()]; + mThread->loadMeshSkinInfo(mPendingSkinRequests.front()); + mPendingSkinRequests.pop(); } - - //sort by "score" - std::sort(mPendingRequests.begin(), mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater()); - - while (!mPendingRequests.empty() && push_count > 0) + + //send decomposition requests + while (!mPendingDecompositionRequests.empty()) { - LLMeshRepoThread::LODRequest& request = mPendingRequests.front(); - mThread->loadMeshLOD(request.mMeshParams, request.mLOD); - mPendingRequests.erase(mPendingRequests.begin()); - LLMeshRepository::sLODPending--; - push_count--; + mThread->loadMeshDecomposition(mPendingDecompositionRequests.front()); + mPendingDecompositionRequests.pop(); } - } - - //send skin info requests - while (!mPendingSkinRequests.empty()) - { - mThread->loadMeshSkinInfo(mPendingSkinRequests.front()); - mPendingSkinRequests.pop(); - } - //send decomposition requests - while (!mPendingDecompositionRequests.empty()) - { - mThread->loadMeshDecomposition(mPendingDecompositionRequests.front()); - mPendingDecompositionRequests.pop(); - } + //send physics shapes decomposition requests + while (!mPendingPhysicsShapeRequests.empty()) + { + mThread->loadMeshPhysicsShape(mPendingPhysicsShapeRequests.front()); + mPendingPhysicsShapeRequests.pop(); + } - //send physics shapes decomposition requests - while (!mPendingPhysicsShapeRequests.empty()) - { - mThread->loadMeshPhysicsShape(mPendingPhysicsShapeRequests.front()); - mPendingPhysicsShapeRequests.pop(); + mThread->notifyLoadedMeshes(); } - - mThread->notifyLoadedMeshes(); - - mThread->mMutex->unlock(); - mMeshMutex->unlock(); mThread->mSignal->signal(); } @@ -3091,13 +3119,14 @@ void LLPhysicsDecomp::doDecomposition() num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(stage); } - mMutex->lock(); - mCurRequest->mHull.clear(); - mCurRequest->mHull.resize(num_hulls); + { + LLMutexLock lock(mMutex); + mCurRequest->mHull.clear(); + mCurRequest->mHull.resize(num_hulls); - mCurRequest->mHullMesh.clear(); - mCurRequest->mHullMesh.resize(num_hulls); - mMutex->unlock(); + mCurRequest->mHullMesh.clear(); + mCurRequest->mHullMesh.resize(num_hulls); + } for (S32 i = 0; i < num_hulls; ++i) { @@ -3121,14 +3150,14 @@ void LLPhysicsDecomp::doDecomposition() get_vertex_buffer_from_mesh(mesh, mCurRequest->mHullMesh[i]); - mMutex->lock(); - mCurRequest->mHull[i] = p; - mMutex->unlock(); + { + LLMutexLock lock(mMutex); + mCurRequest->mHull[i] = p; + } } { LLMutexLock lock(mMutex); - mCurRequest->setStatusMessage("FAIL"); completeCurrent(); } @@ -3196,7 +3225,6 @@ void LLPhysicsDecomp::doDecompositionSingleHull() LLCDMeshData mesh; -#if 1 setMeshData(mesh, true); LLCDResult ret = decomp->buildSingleHull() ; @@ -3207,11 +3235,12 @@ void LLPhysicsDecomp::doDecompositionSingleHull() } else { - mMutex->lock(); - mCurRequest->mHull.clear(); - mCurRequest->mHull.resize(1); - mCurRequest->mHullMesh.clear(); - mMutex->unlock(); + { + LLMutexLock lock(mMutex); + mCurRequest->mHull.clear(); + mCurRequest->mHull.resize(1); + mCurRequest->mHullMesh.clear(); + } std::vector p; LLCDHull hull; @@ -3227,93 +3256,12 @@ void LLPhysicsDecomp::doDecompositionSingleHull() p.push_back(vert); v = (F32*) (((U8*) v) + hull.mVertexStrideBytes); } - - mMutex->lock(); - mCurRequest->mHull[0] = p; - mMutex->unlock(); - } -#else - setMeshData(mesh, false); - - //set all parameters to default - std::map param_map; - - static const LLCDParam* params = NULL; - static S32 param_count = 0; - - if (!params) - { - param_count = decomp->getParameters(¶ms); - } - - for (S32 i = 0; i < param_count; ++i) - { - decomp->setParam(params[i].mName, params[i].mDefault.mIntOrEnumValue); - } - - const S32 STAGE_DECOMPOSE = mStageID["Decompose"]; - const S32 STAGE_SIMPLIFY = mStageID["Simplify"]; - const S32 DECOMP_PREVIEW = 0; - const S32 SIMPLIFY_RETAIN = 0; - - decomp->setParam("Decompose Quality", DECOMP_PREVIEW); - decomp->setParam("Simplify Method", SIMPLIFY_RETAIN); - decomp->setParam("Retain%", 0.f); - - LLCDResult ret = LLCD_OK; - ret = decomp->executeStage(STAGE_DECOMPOSE); - - if (ret) - { - llwarns << "Could not execute decomposition stage when attempting to create single hull." << llendl; - make_box(mCurRequest); - } - else - { - ret = decomp->executeStage(STAGE_SIMPLIFY); - - if (ret) - { - llwarns << "Could not execute simiplification stage when attempting to create single hull." << llendl; - make_box(mCurRequest); - } - else + { - S32 num_hulls =0; - if (LLConvexDecomposition::getInstance() != NULL) - { - num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(STAGE_SIMPLIFY); - } - - mMutex->lock(); - mCurRequest->mHull.clear(); - mCurRequest->mHull.resize(num_hulls); - mCurRequest->mHullMesh.clear(); - mMutex->unlock(); - - for (S32 i = 0; i < num_hulls; ++i) - { - std::vector p; - LLCDHull hull; - // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code - LLConvexDecomposition::getInstance()->getHullFromStage(STAGE_SIMPLIFY, i, &hull); - - const F32* v = hull.mVertexBase; - - for (S32 j = 0; j < hull.mNumVertices; ++j) - { - LLVector3 vert(v[0], v[1], v[2]); - p.push_back(vert); - v = (F32*) (((U8*) v) + hull.mVertexStrideBytes); - } - - mMutex->lock(); - mCurRequest->mHull[i] = p; - mMutex->unlock(); - } + LLMutexLock lock(mMutex); + mCurRequest->mHull[0] = p; } - } -#endif + } { completeCurrent(); -- cgit v1.2.3