I've been investigating a crash that has plagued us for quite some time. I've
finally gotten some time to sit down and take a look at this.
Details:
OSG: 2.8.1
OS: WinXP SP3 32Bit
CPU: 8 Core 2.5GHz Xenon
Graphics: Quadro FX 3700 512 MB
Memory: Plenty
Description:
Our application embeds OSG into two views. There are multiple threads at work
here, but the two of importance are the Map thread and the DatabasePager thread.
At certain points during the execution of our application, the Map thread will
be given a request to create an osgText object. One of the operations is to
request a font for the osgText object. At this point we call down into
osgText::readFontFile( ... ).
At this same time, the database pager is hard at work reading paged files from
disk on its own thread. At some point, the database pager gets into
Registry::readImplementation( ... ) and begins to copy the object cache to a
temp object cache. There is only one object in the cache and it is an
osgText::Font object. At some point during this stage, an unref of the object
happens. Here is where the oddity comes in. When the object is getting
unreferenced, the code checks to see if the object needs to be deleted. For
some odd reason this value is 0 on the DB thread but 2 on the Map thread. When
the Map thread tries to use the font object, it dies, as the DB thread has
already released it. I would give more details on this, but the computer I was
working on did not come back from standby and everything I am stating is from
memory. Sorry.
Question:
Now that we have gotten through that, the question I have is related to the
implementation of osgText::readFontFile. Would it not be safer to have this
function use ref_ptr objects internally rather than standard pointers? I'm
quite confused as to the design decisions behind this and hope someone can help
me here.
Code:
osgText::Font* osgText::readFontFile(const std::string& filename, const
osgDB::ReaderWriter::Options* userOptions)
{
if (filename=="") return 0;
std::string foundFile = findFontFile(filename);
if (foundFile.empty()) return 0;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_FontFileMutex);
osg::ref_ptr<osgDB::ReaderWriter::Options> localOptions;
if (!userOptions)
{
localOptions = new osgDB::ReaderWriter::Options;
localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
}
osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ?
userOptions : localOptions.get());
// if the object is a font then return it.
osgText::Font* font = dynamic_cast<osgText::Font*>(object);
if (font) return font;
// otherwise if the object has zero references then delete it by doing
another unref().
if (object && object->referenceCount()==0) object->unref();
return 0;
}
Thanks,
Ryan
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=21314#21314
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org