SH-4516 Fix a subset of thread races in llmeshrepository

Thu, 19 Sep 2013 19:20:31 -0400

author
Monty Brandenberg <monty@lindenlab.com>
date
Thu, 19 Sep 2013 19:20:31 -0400
changeset 40727
f2b0a9f7b1c0
parent 40726
ea87b029d00c
child 40728
a0591d41b496

SH-4516 Fix a subset of thread races in llmeshrepository
Much earlier identified some thread races including two on mskininfoq
and mdecompositionq. I actually hit one in testing the other day so
I'm fixing them now. Put them under the mMutex lock and use the
mutex in such a way that main thread stalls are not added.

indra/newview/llmeshrepository.cpp file | annotate | diff | revisions
     1.1 --- a/indra/newview/llmeshrepository.cpp	Thu Sep 19 13:13:37 2013 -0400
     1.2 +++ b/indra/newview/llmeshrepository.cpp	Thu Sep 19 19:20:31 2013 -0400
     1.3 @@ -246,10 +246,10 @@
     1.4  //     mMeshHeader              mHeaderMutex  rw.repo.mHeaderMutex, ro.main.mHeaderMutex, ro.main.none [0]
     1.5  //     mMeshHeaderSize          mHeaderMutex  rw.repo.mHeaderMutex
     1.6  //     mSkinRequests            mMutex        rw.repo.mMutex, ro.repo.none [5]
     1.7 -//     mSkinInfoQ               none          rw.repo.none, rw.main.mMutex [0]
     1.8 +//     mSkinInfoQ               mMutex        rw.repo.mMutex, rw.main.mMutex [5] (was:  [0])
     1.9  //     mDecompositionRequests   mMutex        rw.repo.mMutex, ro.repo.none [5]
    1.10  //     mPhysicsShapeRequests    mMutex        rw.repo.mMutex, ro.repo.none [5]
    1.11 -//     mDecompositionQ          none          rw.repo.none, rw.main.mMutex [0]
    1.12 +//     mDecompositionQ          mMutex        rw.repo.mMutex, rw.main.mMutex [5] (was:  [0])
    1.13  //     mHeaderReqQ              mMutex        ro.repo.none [5], rw.repo.mMutex, rw.any.mMutex
    1.14  //     mLODReqQ                 mMutex        ro.repo.none [5], rw.repo.mMutex, rw.any.mMutex
    1.15  //     mUnavailableQ            mMutex        rw.repo.none [0], ro.main.none [5], rw.main.mMutex
    1.16 @@ -1713,7 +1713,10 @@
    1.17  		info.mMeshID = mesh_id;
    1.18  
    1.19  		// LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL;
    1.20 -		mSkinInfoQ.push(info);
    1.21 +		{
    1.22 +			LLMutexLock lock(mMutex);
    1.23 +			mSkinInfoQ.push(info);
    1.24 +		}
    1.25  	}
    1.26  
    1.27  	return true;
    1.28 @@ -1740,7 +1743,10 @@
    1.29  	{
    1.30  		LLModel::Decomposition* d = new LLModel::Decomposition(decomp);
    1.31  		d->mMeshID = mesh_id;
    1.32 -		mDecompositionQ.push(d);
    1.33 +		{
    1.34 +			LLMutexLock lock(mMutex);
    1.35 +			mDecompositionQ.push(d);
    1.36 +		}
    1.37  	}
    1.38  
    1.39  	return true;
    1.40 @@ -1799,7 +1805,10 @@
    1.41  		}
    1.42  	}
    1.43  
    1.44 -	mDecompositionQ.push(d);
    1.45 +	{
    1.46 +		LLMutexLock lock(mMutex);
    1.47 +		mDecompositionQ.push(d);
    1.48 +	}
    1.49  	return true;
    1.50  }
    1.51  
    1.52 @@ -2460,16 +2469,30 @@
    1.53  		gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD);
    1.54  	}
    1.55  
    1.56 -	while (!mSkinInfoQ.empty())
    1.57 +	if (! mSkinInfoQ.empty() || ! mDecompositionQ.empty())
    1.58  	{
    1.59 -		gMeshRepo.notifySkinInfoReceived(mSkinInfoQ.front());
    1.60 -		mSkinInfoQ.pop();
    1.61 -	}
    1.62 -
    1.63 -	while (!mDecompositionQ.empty())
    1.64 -	{
    1.65 -		gMeshRepo.notifyDecompositionReceived(mDecompositionQ.front());
    1.66 -		mDecompositionQ.pop();
    1.67 +		std::queue<LLMeshSkinInfo> skin_info_q;
    1.68 +		std::queue<LLModel::Decomposition*> decomp_q;
    1.69 +
    1.70 +		if (mMutex->trylock())
    1.71 +		{
    1.72 +			// Make thread-shared data private with swap under lock.
    1.73 +			skin_info_q.swap(mSkinInfoQ);
    1.74 +			decomp_q.swap(mDecompositionQ);
    1.75 +			mMutex->unlock();
    1.76 +
    1.77 +			while (! skin_info_q.empty())
    1.78 +			{
    1.79 +				gMeshRepo.notifySkinInfoReceived(skin_info_q.front());
    1.80 +				skin_info_q.pop();
    1.81 +			}
    1.82 +
    1.83 +			while (! decomp_q.empty())
    1.84 +			{
    1.85 +				gMeshRepo.notifyDecompositionReceived(decomp_q.front());
    1.86 +				decomp_q.pop();
    1.87 +			}
    1.88 +		}
    1.89  	}
    1.90  
    1.91  	if (update_metrics)

mercurial