From 9dc35ce47a28f791ef12a3dd03058696a2426fa3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 6 Sep 2004 18:20:38 +0000 Subject: [PATCH] Added mutex to access to the Registry::_objectCache. --- include/osgDB/Registry | 9 +-- src/osgDB/Registry.cpp | 130 +++++++++++++++++++++++++++-------------- 2 files changed, 91 insertions(+), 48 deletions(-) diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 6839cbc63..9e16a9b18 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -428,11 +428,12 @@ class OSGDB_EXPORT Registry : public osg::Referenced // options to pass to reader writers. osg::ref_ptr _options; - FilePathList _dataFilePath; - FilePathList _libraryFilePath; + FilePathList _dataFilePath; + FilePathList _libraryFilePath; - CacheHintOptions _useObjectCacheHint; - ObjectCache _objectCache; + CacheHintOptions _useObjectCacheHint; + ObjectCache _objectCache; + OpenThreads::Mutex _objectCacheMutex; osg::ref_ptr _databasePager; osg::ref_ptr _sharedStateManager; diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index a9e83eeda..ba68f0149 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -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 "<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 lock(_objectCacheMutex); + ObjectCache::iterator oitr=_objectCache.find(file); + if (oitr!=_objectCache.end()) + { + notify(INFO)<<"returning cached instanced of "<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 lock(_objectCacheMutex); + tmpObjectCache.swap(_objectCache); + } + PushAndPopDataPath tmpfile(getFilePath(file)); ReaderWriter::ReadResult rr = readObject(file); - tmpObjectCache.swap(_objectCache); - + { + OpenThreads::ScopedLock 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 "<(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 lock(_objectCacheMutex); + ObjectCache::iterator oitr=_objectCache.find(file); + if (oitr!=_objectCache.end()) + { + notify(INFO)<< "returning cached instanced of "<(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 lock(_objectCacheMutex); + tmpObjectCache.swap(_objectCache); + } PushAndPopDataPath tmpfile(getFilePath(file)); ReaderWriter::ReadResult rr = readImage(file); - tmpObjectCache.swap(_objectCache); + { + OpenThreads::ScopedLock 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 "<(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 lock(_objectCacheMutex); + ObjectCache::iterator oitr=_objectCache.find(file); + if (oitr!=_objectCache.end()) + { + notify(INFO)<< "returning cached instanced of "<(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 lock(_objectCacheMutex); + tmpObjectCache.swap(_objectCache); + } + PushAndPopDataPath tmpfile(getFilePath(file)); ReaderWriter::ReadResult rr = readHeightField(file); - tmpObjectCache.swap(_objectCache); + { + OpenThreads::ScopedLock 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 "<(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 lock(_objectCacheMutex); + ObjectCache::iterator oitr=_objectCache.find(file); + if (oitr!=_objectCache.end()) + { + notify(INFO)<< "returning cached instanced of "<(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 lock(_objectCacheMutex); + tmpObjectCache.swap(_objectCache); + } + PushAndPopDataPath tmpfile(getFilePath(file)); ReaderWriter::ReadResult rr = readNode(file); - tmpObjectCache.swap(_objectCache); - + { + OpenThreads::ScopedLock 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 lock(_objectCacheMutex); + _objectCache[filename]=ObjectTimeStampPair(object,timestamp); } void Registry::updateTimeStampOfObjectsInCacheWithExtenalReferences(double currentTime) { + OpenThreads::ScopedLock 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 lock(_objectCacheMutex); + typedef std::vector ObjectsToRemove; ObjectsToRemove objectsToRemove; @@ -1776,6 +1817,7 @@ void Registry::removeExpiredObjectsInCache(double expiryTime) void Registry::clearObjectCache() { + OpenThreads::ScopedLock lock(_objectCacheMutex); _objectCache.clear(); }