Use observer_ptr::lock for thread-safe pointer retrieval.

Also revert to using ref_ptr for the top-level EffectMap, since it holds
elements no one else references (and don't affect memory much).
This commit is contained in:
ThorstenB 2012-04-02 20:09:02 +02:00
parent b95fb48a16
commit 9ad070871a
6 changed files with 27 additions and 26 deletions

View File

@ -291,20 +291,20 @@ Texture* TexBuilder<T>::build(Effect* effect, Pass* pass, const SGPropertyNode*
TexTuple attrs = makeTexTuple(effect, props, options, _type);
typename TexMap::iterator itr = texMap.find(attrs);
if (itr != texMap.end())
ref_ptr<T> tex;
if ((itr != texMap.end())&&
(itr->second.lock(tex)))
{
T* tex = itr->second.get();
if (tex)
return tex;
return tex.release();
}
T* tex = new T;
tex = new T;
setAttrs(attrs, tex, options);
if (itr == texMap.end())
texMap.insert(make_pair(attrs, tex));
else
itr->second = tex; // update existing, but empty observer
return tex;
return tex.release();
}

View File

@ -44,7 +44,7 @@ using namespace osg;
using namespace effect;
typedef vector<const SGPropertyNode*> RawPropVector;
typedef map<const string, observer_ptr<Effect> > EffectMap;
typedef map<const string, ref_ptr<Effect> > EffectMap;
namespace
{
@ -206,10 +206,10 @@ Effect* makeEffect(SGPropertyNode* prop,
lock(effectMutex);
cache = parent->getCache();
itr = cache->find(key);
if (itr != cache->end()) {
effect = itr->second.get();
if (effect.valid())
effect->generator = parent->generator; // Copy the generators
if ((itr != cache->end())&&
itr->second.lock(effect))
{
effect->generator = parent->generator; // Copy the generators
}
}
if (!effect.valid()) {
@ -222,8 +222,8 @@ Effect* makeEffect(SGPropertyNode* prop,
pair<Effect::Cache::iterator, bool> irslt
= cache->insert(make_pair(key, effect));
if (!irslt.second) {
ref_ptr<Effect> old = irslt.first->second.get();
if (old.valid())
ref_ptr<Effect> old;
if (irslt.first->second.lock(old))
effect = old; // Another thread beat us in creating it! Discard our own...
else
irslt.first->second = effect; // update existing, but empty observer

View File

@ -378,6 +378,8 @@ SGMaterial::init ()
Effect* SGMaterial::get_effect(int i)
{
if(!_status[i].effect_realized) {
if (!_status[i].effect.valid())
return 0;
_status[i].effect->realizeTechniques(_status[i].options.get());
_status[i].effect_realized = true;
}
@ -459,7 +461,8 @@ void SGMaterial::buildEffectProperties(const SGReaderWriterOptions* options)
makeChild(effectParamProp, "light-coverage")->setDoubleValue(light_coverage);
matState.effect = makeEffect(effectProp, false, options);
matState.effect->setUserData(user.get());
if (matState.effect.valid())
matState.effect->setUserData(user.get());
}
}

View File

@ -103,11 +103,8 @@ SGNewCloud::SGNewCloud(const SGPath &texture_root, const SGPropertyNode *cld_def
// Create a new Effect for the texture, if required.
EffectMap::iterator iter = effectMap.find(texture);
if (iter != effectMap.end()) {
effect = iter->second.get();
}
if (!effect.valid())
if ((iter == effectMap.end())||
(!iter->second.lock(effect)))
{
SGPropertyNode_ptr pcloudEffect = new SGPropertyNode;
makeChild(pcloudEffect, "inherits-from")->setValue("Effects/cloud");

View File

@ -302,10 +302,8 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
ref_ptr<Effect> effect;
EffectMap::iterator iter = treeEffectMap.find(forest->texture);
if (iter != treeEffectMap.end())
effect = iter->second.get();
if (!effect.valid())
if ((iter == treeEffectMap.end())||
(!iter->second.lock(effect)))
{
SGPropertyNode_ptr effectProp = new SGPropertyNode;
makeChild(effectProp, "inherits-from")->setStringValue("Effects/tree");

View File

@ -174,9 +174,12 @@ Effect* getLightEffect(float size, const Vec3& attenuation,
PointParams pointParams(size, attenuation, minSize, maxSize, directional);
ScopedLock<Mutex> lock(lightMutex);
EffectMap::iterator eitr = effectMap.find(pointParams);
if ((eitr != effectMap.end())&&
eitr->second.valid())
return eitr->second.get();
if (eitr != effectMap.end())
{
ref_ptr<Effect> effect;
if (eitr->second.lock(effect))
return effect.release();
}
// Basic stuff; no sprite or attenuation support
Pass *basicPass = new Pass;
basicPass->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");