From 67f98edc0587958a2e375f111ca0f009308bf8ac Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Jun 2014 11:11:59 +0000 Subject: [PATCH] From Lauren Voerman, "In order to speed up loading large scenes (especially from network disk) I added code to our viewer to setup multiple database-pagers and request the files trough a database-request: databasePager->setUpThreads(16, 1); We experienced problems with multiple databasepagers loading files in parallel, when two threads start to load the same file (usually a texture referenced by multiple models). The second thread to add the file to the cache (sometimes) manages to do so while the refcount from the cached object still is zero, causing the object loaded to be destroyed. Sometimes the second thread manages to ref() the object before Referenced::signalObserversAndDelete does the final recount check, causing a warning: "Warning Referenced::signalObserversAndDelete(,,) doing delete with _refCount=1" With a deleted object added to the scenegraph we get some undesired results, I think the program only crashes if the object was a Node, and just has some untextured surfaces if it was a texture, but I'm not completely sure. Attached is a modified version of the Registry.cpp, returning the object in cache and let the duplicate loaded object to be destroyed. A more efficient option would be to add some sort of blocking entry to the objectcache to stop the second thread from reading the file, and just wait until the first thread added it to the cache. If you think that's worthwile we would be happy to implement that version. A bit tricky to implement and test, that's why I submit a simple version that stops my program from crashing." git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14300 16af8721-9629-0410-8352-f15c8da7e697 --- src/osgDB/Registry.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 494c44bc9..c64f612b4 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -1250,9 +1250,21 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun ReaderWriter::ReadResult rr = read(readFunctor); if (rr.validObject()) { - // update cache with new entry. - OSG_INFO<<"Adding to object cache "< lock(_objectCacheMutex); + ObjectCache::iterator oitr = _objectCache.find(file); + if (oitr != _objectCache.end()) + { + OSG_INFO << "returning cached instanced of " << file << std::endl; + if (readFunctor.isValid(oitr->second.first.get())) return ReaderWriter::ReadResult(oitr->second.first.get(), ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE); + else return ReaderWriter::ReadResult("Error file does not contain an osg::Object"); + } + // update cache with new entry. + OSG_INFO<<"Adding to object cache "<