Added mutex to access to the Registry::_objectCache.

This commit is contained in:
Robert Osfield
2004-09-06 18:20:38 +00:00
parent 4571238459
commit 9dc35ce47a
2 changed files with 91 additions and 48 deletions

View File

@@ -428,11 +428,12 @@ class OSGDB_EXPORT Registry : public osg::Referenced
// options to pass to reader writers.
osg::ref_ptr<ReaderWriter::Options> _options;
FilePathList _dataFilePath;
FilePathList _libraryFilePath;
FilePathList _dataFilePath;
FilePathList _libraryFilePath;
CacheHintOptions _useObjectCacheHint;
ObjectCache _objectCache;
CacheHintOptions _useObjectCacheHint;
ObjectCache _objectCache;
OpenThreads::Mutex _objectCacheMutex;
osg::ref_ptr<DatabasePager> _databasePager;
osg::ref_ptr<SharedStateManager> _sharedStateManager;

View File

@@ -211,14 +211,14 @@ Registry::~Registry()
// clean up the SharedStateManager
_sharedStateManager = 0;
// object cache clear needed here to prevent crash in unref() of
// the objects it contains when running the TXP plugin.
// Not sure why, but perhaps there is is something in a TXP plugin
// which is deleted the data before its ref count hits zero, perhaps
// even some issue with objects be allocated by a plugin that is
// mainted after that plugin is deleted... Robert Osfield, Jan 2004.
_objectCache.clear();
clearObjectCache();
// unload all the plugin before we finally destruct.
closeAllLibraries();
@@ -1190,15 +1190,18 @@ ReaderWriter::ReadResult Registry::readObjectImplementation(const std::string& c
if (useObjectCache & CACHE_OBJECTS)
{
// search for entry in the object cache.
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<<"returning cached instanced of "<<file<<std::endl;
osg::Object* object = oitr->second.first.get();
if (object) return ReaderWriter::ReadResult(object, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file does not contain an osg::Object");
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<<"returning cached instanced of "<<file<<std::endl;
osg::Object* object = oitr->second.first.get();
if (object) return ReaderWriter::ReadResult(object, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file does not contain an osg::Object");
}
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readObject(file);
@@ -1216,14 +1219,21 @@ ReaderWriter::ReadResult Registry::readObjectImplementation(const std::string& c
{
ObjectCache tmpObjectCache;
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readObject(file);
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
return rr;
}
@@ -1336,15 +1346,18 @@ ReaderWriter::ReadResult Registry::readImageImplementation(const std::string& fi
if (useObjectCache & CACHE_IMAGES)
{
// search for entry in the object cache.
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<< "returning cached instanced of "<<file<<std::endl;
osg::Image* image = dynamic_cast<osg::Image*>(oitr->second.first.get());
if (image) return ReaderWriter::ReadResult(image, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file not of type osg::Image");
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<< "returning cached instanced of "<<file<<std::endl;
osg::Image* image = dynamic_cast<osg::Image*>(oitr->second.first.get());
if (image) return ReaderWriter::ReadResult(image, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file not of type osg::Image");
}
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readImage(file);
@@ -1364,13 +1377,19 @@ ReaderWriter::ReadResult Registry::readImageImplementation(const std::string& fi
{
ObjectCache tmpObjectCache;
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readImage(file);
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
return rr;
@@ -1486,15 +1505,18 @@ ReaderWriter::ReadResult Registry::readHeightFieldImplementation(const std::stri
if (useObjectCache & CACHE_HEIGHTFIELDS)
{
// search for entry in the object cache.
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<< "returning cached instanced of "<<file<<std::endl;
osg::HeightField* heightField = dynamic_cast<osg::HeightField*>(oitr->second.first.get());
if (heightField) return ReaderWriter::ReadResult(heightField, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file not of type osg::HeightField");
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<< "returning cached instanced of "<<file<<std::endl;
osg::HeightField* heightField = dynamic_cast<osg::HeightField*>(oitr->second.first.get());
if (heightField) return ReaderWriter::ReadResult(heightField, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file not of type osg::HeightField");
}
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readHeightField(file);
@@ -1514,13 +1536,19 @@ ReaderWriter::ReadResult Registry::readHeightFieldImplementation(const std::stri
{
ObjectCache tmpObjectCache;
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readHeightField(file);
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
return rr;
@@ -1648,15 +1676,18 @@ ReaderWriter::ReadResult Registry::readNodeImplementation(const std::string& fil
if (useObjectCache & CACHE_NODES)
{
// search for entry in the object cache.
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<< "returning cached instanced of "<<file<<std::endl;
osg::Node* node = dynamic_cast<osg::Node*>(oitr->second.first.get());
if (node) return ReaderWriter::ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file not of type osg::Node");
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
ObjectCache::iterator oitr=_objectCache.find(file);
if (oitr!=_objectCache.end())
{
notify(INFO)<< "returning cached instanced of "<<file<<std::endl;
osg::Node* node = dynamic_cast<osg::Node*>(oitr->second.first.get());
if (node) return ReaderWriter::ReadResult(node, ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
else return ReaderWriter::ReadResult("Error file not of type osg::Node");
}
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readNode(file);
@@ -1674,14 +1705,20 @@ ReaderWriter::ReadResult Registry::readNodeImplementation(const std::string& fil
{
ObjectCache tmpObjectCache;
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
PushAndPopDataPath tmpfile(getFilePath(file));
ReaderWriter::ReadResult rr = readNode(file);
tmpObjectCache.swap(_objectCache);
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
tmpObjectCache.swap(_objectCache);
}
return rr;
}
@@ -1725,11 +1762,13 @@ ReaderWriter::WriteResult Registry::writeNodeImplementation(const Node& node,con
void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp)
{
_objectCache[filename]=ObjectTimeStampPair(object,timestamp);
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
_objectCache[filename]=ObjectTimeStampPair(object,timestamp);
}
void Registry::updateTimeStampOfObjectsInCacheWithExtenalReferences(double currentTime)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
// look for objects with external references and update their time stamp.
for(ObjectCache::iterator itr=_objectCache.begin();
@@ -1747,6 +1786,8 @@ void Registry::updateTimeStampOfObjectsInCacheWithExtenalReferences(double curre
void Registry::removeExpiredObjectsInCache(double expiryTime)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
typedef std::vector<std::string> ObjectsToRemove;
ObjectsToRemove objectsToRemove;
@@ -1776,6 +1817,7 @@ void Registry::removeExpiredObjectsInCache(double expiryTime)
void Registry::clearObjectCache()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
_objectCache.clear();
}