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.
"
This commit is contained in:
Robert Osfield
2010-12-12 09:37:14 +00:00
parent c959bab0a6
commit b4dad9bac3
2 changed files with 77 additions and 47 deletions

View File

@@ -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<TXPArchive> >::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="<<id<<")"<<std::endl;
return (_archives.erase(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

View File

@@ -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<TXPArchive::TileLocationInfo>& childrenLoc);