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

Reply via email to