Protect the _programSet in Shader with a mutex.

This prevents thread safety issues when Shader objects are used in
multiple programs.
This commit is contained in:
Jason Beverage 2018-09-04 10:35:38 -04:00 committed by Robert Osfield
parent a06fcbe5d9
commit 6ae1139630
2 changed files with 4 additions and 0 deletions

View File

@ -306,6 +306,7 @@ class OSG_EXPORT Shader : public osg::Object
/** osg::Programs that this osg::Shader is attached to */ /** osg::Programs that this osg::Shader is attached to */
typedef std::set< osg::Program* > ProgramSet; typedef std::set< osg::Program* > ProgramSet;
ProgramSet _programSet; ProgramSet _programSet;
OpenThreads::Mutex _programSetMutex;
mutable osg::buffered_value< osg::ref_ptr<ShaderObjects> > _pcsList; mutable osg::buffered_value< osg::ref_ptr<ShaderObjects> > _pcsList;
private: private:

View File

@ -483,6 +483,7 @@ Shader::PerContextShader* Shader::getPCS(osg::State& state) const
bool Shader::addProgramRef( Program* program ) bool Shader::addProgramRef( Program* program )
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lk(_programSetMutex);
ProgramSet::iterator itr = _programSet.find(program); ProgramSet::iterator itr = _programSet.find(program);
if( itr != _programSet.end() ) return false; if( itr != _programSet.end() ) return false;
@ -492,6 +493,7 @@ bool Shader::addProgramRef( Program* program )
bool Shader::removeProgramRef( Program* program ) bool Shader::removeProgramRef( Program* program )
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lk(_programSetMutex);
ProgramSet::iterator itr = _programSet.find(program); ProgramSet::iterator itr = _programSet.find(program);
if( itr == _programSet.end() ) return false; if( itr == _programSet.end() ) return false;
@ -507,6 +509,7 @@ void Shader::dirtyShader()
if( _pcsList[cxt].valid() ) _pcsList[cxt]->requestCompile(); if( _pcsList[cxt].valid() ) _pcsList[cxt]->requestCompile();
} }
OpenThreads::ScopedLock<OpenThreads::Mutex> lk(_programSetMutex);
// Also mark Programs that depend on us as needing relink. // Also mark Programs that depend on us as needing relink.
for( ProgramSet::iterator itr = _programSet.begin(); for( ProgramSet::iterator itr = _programSet.begin();
itr != _programSet.end(); ++itr ) itr != _programSet.end(); ++itr )