summaryrefslogtreecommitdiff
path: root/indra/newview/llmeshrepository.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llmeshrepository.cpp')
-rw-r--r--indra/newview/llmeshrepository.cpp78
1 files changed, 44 insertions, 34 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index bd4bebbf23..8e5bdc0225 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -99,7 +99,7 @@
// locking actions. In particular, the following operations
// on LLMeshRepository are very averse to any stalls:
// * loadMesh
-// * getMeshHeader (For structural details, see:
+// * search in mMeshHeader (For structural details, see:
// http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format)
// * notifyLoadedMeshes
// * getSkinInfo
@@ -1909,6 +1909,12 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
{
LLMutexLock lock(mMutex);
mLoadedQ.push(mesh);
+ // LLPointer is not thread safe, since we added this pointer into
+ // threaded list, make sure counter gets decreased inside mutex lock
+ // and won't affect mLoadedQ processing
+ volume = NULL;
+ // might be good idea to turn mesh into pointer to avoid making a copy
+ mesh.mVolume = NULL;
}
return MESH_OK;
}
@@ -2861,12 +2867,12 @@ void LLMeshRepoThread::notifyLoadedMeshes()
mMutex->unlock();
break;
}
- LoadedMesh mesh = mLoadedQ.front();
+ LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point
mLoadedQ.pop();
mMutex->unlock();
update_metrics = true;
- if (mesh.mVolume && mesh.mVolume->getNumVolumeFaces() > 0)
+ if (mesh.mVolume->getNumVolumeFaces() > 0)
{
gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume);
}
@@ -3211,7 +3217,6 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
header = iter->second;
}
- gMeshRepo.mThread->mHeaderMutex->unlock();
if (header_bytes > 0
&& !header.has("404")
@@ -3232,7 +3237,10 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
- S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
+ // Do not unlock mutex untill we are done with LLSD.
+ // LLSD is smart and can work like smart pointer, is not thread safe.
+ gMeshRepo.mThread->mHeaderMutex->unlock();
+
S32 bytes = lod_bytes + header_bytes;
@@ -3253,6 +3261,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
{
LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL;
+ gMeshRepo.mThread->mHeaderMutex->unlock();
+
// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
for (int i(0); i < 4; ++i)
@@ -4122,42 +4132,42 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
{
- LLSD mesh = mThread->getMeshHeader(mesh_id);
- if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
- {
- return true;
- }
-
- LLModel::Decomposition* decomp = getDecomposition(mesh_id);
- if (decomp && !decomp->mHull.empty())
- {
- return true;
- }
+ if (mesh_id.isNull())
+ {
+ return false;
+ }
- return false;
-}
+ if (mThread->hasPhysicsShapeInHeader(mesh_id))
+ {
+ return true;
+ }
-LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
-{
- LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
+ LLModel::Decomposition* decomp = getDecomposition(mesh_id);
+ if (decomp && !decomp->mHull.empty())
+ {
+ return true;
+ }
- return mThread->getMeshHeader(mesh_id);
+ return false;
}
-LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
+bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
{
- static LLSD dummy_ret;
- if (mesh_id.notNull())
- {
- LLMutexLock lock(mHeaderMutex);
- mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
- if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0)
- {
- return iter->second;
- }
- }
+ LLMutexLock lock(mHeaderMutex);
+ if (mMeshHeaderSize[mesh_id] > 0)
+ {
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ if (iter != mMeshHeader.end())
+ {
+ LLSD &mesh = iter->second;
+ if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+ {
+ return true;
+ }
+ }
+ }
- return dummy_ret;
+ return false;
}