From b4dad9bac38c073f65fcca1724f49d2d5b441918 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 12 Dec 2010 09:37:14 +0000 Subject: [PATCH] From David Fries, "Avoid a terrapage crash with outstanding requests to a removed archive file. ReaderWriterTXP::getArchiveName will create an archive if it doesn't exist. This is causing a crash if the terrain is removed and there are outstanding database requests in the database pager. The request will create a new archive, and as the archive is newly create doesn't have the materials etc to support the subtile that was just loaded. To fix the problem getArchiveName will only return existing archives. createArchiveName was added to create archives. " --- src/osgPlugins/txp/ReaderWriterTXP.cpp | 122 +++++++++++++++---------- src/osgPlugins/txp/ReaderWriterTXP.h | 2 + 2 files changed, 77 insertions(+), 47 deletions(-) diff --git a/src/osgPlugins/txp/ReaderWriterTXP.cpp b/src/osgPlugins/txp/ReaderWriterTXP.cpp index aba94335d..9bae4abea 100644 --- a/src/osgPlugins/txp/ReaderWriterTXP.cpp +++ b/src/osgPlugins/txp/ReaderWriterTXP.cpp @@ -58,7 +58,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::strin //we will set our osgdb loader options on the archive and set the appropriate archive on //the txpNode. int id = ++_archiveId; - osg::ref_ptr< TXPArchive > archive = getArchive(id,osgDB::getFilePath(fileName)); + osg::ref_ptr< TXPArchive > archive = createArchive(id,osgDB::getFilePath(fileName)); if (archive != NULL) { @@ -86,6 +86,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::strin unsigned int id; sscanf(name.c_str(),"tile%d_%dx%d_%u",&lod,&x,&y,&id); osg::ref_ptr< TXPArchive > archive = getArchive(id,osgDB::getFilePath(file)); + if (archive == NULL) + return ReadResult::ERROR_IN_READING_FILE; // The way this is done a 'tile' should only be created for lod 0 only, // something is wrong if this is no the case @@ -199,6 +201,8 @@ osgDB::ReaderWriter::ReadResult ReaderWriterTXP::local_readNode(const std::strin unsigned int id; sscanf(name.c_str(),"subtiles%d_%dx%d_%u",&lod,&x,&y,&id); osg::ref_ptr< TXPArchive > archive = getArchive(id,osgDB::getFilePath(file)); + if (archive == NULL) + return ReadResult::ERROR_IN_READING_FILE; int majorVersion, minorVersion; archive->GetVersion(majorVersion, minorVersion); @@ -563,63 +567,82 @@ bool ReaderWriterTXP::extractChildrenLocations(const std::string& name, int pare } +std::string ReaderWriterTXP::getArchiveName(const std::string& dir) +{ +#ifdef _WIN32 + const char _PATHD = '\\'; +#elif defined(macintosh) + const char _PATHD = ':'; +#else + const char _PATHD = '/'; +#endif + + return dir+_PATHD+"archive.txp"; +} + osg::ref_ptr< TXPArchive > ReaderWriterTXP::getArchive(int id, const std::string& dir) { osg::ref_ptr< TXPArchive > archive = NULL; std::map< int,osg::ref_ptr >::iterator iter = _archives.find(id); - if (iter != _archives.end()) { archive = iter->second.get(); } - - if (archive == NULL) + else { -#ifdef _WIN32 - const char _PATHD = '\\'; -#elif defined(macintosh) - const char _PATHD = ':'; -#else - const char _PATHD = '/'; -#endif - std::string archiveName = dir+_PATHD+"archive.txp"; - archive = new TXPArchive; - if (archive->openFile(archiveName) == false) - { - ReaderWriterTXPERROR("getArchive()") << "failed to load archive: \"" << archiveName << "\"" << std::endl; - return NULL; - } - - if (archive->loadMaterials() == false) - { - ReaderWriterTXPERROR("getArchive()") << "failed to load materials from archive: \"" << archiveName << "\"" << std::endl; - return NULL; - } - - if (archive->loadModels() == false) - { - ReaderWriterTXPERROR("getArchive()") << "failed to load models from archive: \"" << archiveName << "\"" << std::endl; - return NULL; - } - - if (archive->loadLightAttributes() == false) - { - ReaderWriterTXPERROR("getArchive()") << "failed to load light attributes from archive: \"" << archiveName << "\"" << std::endl; - return NULL; - } - - if (archive->loadTextStyles() == false) - { - ReaderWriterTXPERROR("getArchive()") << "failed to load text styles from archive: \"" << archiveName << "\"" << std::endl; - return NULL; - } - - archive->setId(id); - - _archives[id] = archive; + std::string archiveName = getArchiveName(dir); + ReaderWriterTXPERROR("getArchive()") << "archive id " << id << " not found: \"" << archiveName << "\"" << std::endl; } + return archive; +} + +osg::ref_ptr< TXPArchive > ReaderWriterTXP::createArchive(int id, const std::string& dir) +{ + std::string archiveName = getArchiveName(dir); + + osg::ref_ptr< TXPArchive > archive = getArchive(id, dir); + if (archive != NULL) + { + ReaderWriterTXPERROR("createArchive()") << "archive id " << id << " already exists: \"" << archiveName << "\"" << std::endl; + return NULL; + } + + archive = new TXPArchive; + if (archive->openFile(archiveName) == false) + { + ReaderWriterTXPERROR("createArchive()") << "failed to load archive: \"" << archiveName << "\"" << std::endl; + return NULL; + } + + if (archive->loadMaterials() == false) + { + ReaderWriterTXPERROR("createArchive()") << "failed to load materials from archive: \"" << archiveName << "\"" << std::endl; + return NULL; + } + + if (archive->loadModels() == false) + { + ReaderWriterTXPERROR("createArchive()") << "failed to load models from archive: \"" << archiveName << "\"" << std::endl; + return NULL; + } + + if (archive->loadLightAttributes() == false) + { + ReaderWriterTXPERROR("createArchive()") << "failed to load light attributes from archive: \"" << archiveName << "\"" << std::endl; + return NULL; + } + + if (archive->loadTextStyles() == false) + { + ReaderWriterTXPERROR("createArchive()") << "failed to load text styles from archive: \"" << archiveName << "\"" << std::endl; + return NULL; + } + + archive->setId(id); + + _archives[id] = archive; return archive; } @@ -627,7 +650,12 @@ osg::ref_ptr< TXPArchive > ReaderWriterTXP::getArchive(int id, const std::string bool ReaderWriterTXP::removeArchive( int id ) { OSG_INFO<<"ReaderWriterTXP::removeArchive(id="<= 1); + //return (_archives.erase(id) >= 1); + bool result=_archives.erase(id) >= 1; + OSG_WARN<<"remove archive " << id << " size " << _archives.size() + << " result " << result << std::endl; + return result; + } class SeamFinder: public osg::NodeVisitor diff --git a/src/osgPlugins/txp/ReaderWriterTXP.h b/src/osgPlugins/txp/ReaderWriterTXP.h index 41646b7fa..a49beb98e 100644 --- a/src/osgPlugins/txp/ReaderWriterTXP.h +++ b/src/osgPlugins/txp/ReaderWriterTXP.h @@ -81,6 +81,8 @@ protected: ReadResult local_readNode(const std::string& file, const osgDB::ReaderWriter::Options* options); + std::string getArchiveName(const std::string& dir); + osg::ref_ptr< TXPArchive > createArchive(int id, const std::string& dir); osg::ref_ptr< TXPArchive > getArchive(int id, const std::string&); osg::Node* getTileContent(const TXPArchive::TileInfo &info, int x, int y, int lod, TXPArchive* archive, std::vector& childrenLoc);