Hello,

Summary:

Since upgrading to OSG 3.2, our application will crash during render while 
loading a legacy .OSG file on a worker thread. The legacy/deprecated OSG code 
will load objects that are put into the object cache, but then use "takeImage" 
to get a raw pointer to a ref-counted object. If the threads are serviced in a 
particular order the main thread will do cache cleanup and delete this object 
that looks like it has no references while the load thread is pre-empted.

More Detail:

In this use case, the rendered scene graph is empty, and the loaded assets are 
not introduced into the scene graph until the worker thread returns. Let me map 
out the basic flow of the error case (not that freezing the worker thread when 
it has the raw pointer can trigger this crash every time):


Code:

WORKER THREAD:
* Texture2D_readLocalData (src/OsgWrappers/deprecated-dotosg/osg/Texture2D.cpp) 
calls:
* Input::readImage(), which calls 
* osgDB::readImageFile(), which uses rr.takeImage() to return a raw pointer.
* NOTE: the only reference count to the Image at this point is from the cache 
object.

MAIN THREAD:
* Registry::updateTimeStampOfObjectsInCacheWithExternalReferences()
*** timestamp is not updated because there are no counted external references!
* Registry::removeExpiredObjectsInCache()
*** this deletes the object because the timestamp was not updated above.

WORKER THREAD:
* raw Image pointer is added to the texture, but it's not valid at this point. 
Crash ensues.


  

There are several fixes I can think of offhand, some seem more proper than 
others. I'm not sure why the raw pointer usage is there, it would seem to 
violate the principle of the smart pointers.

POSSIBLE FIXES:

 1. Remove code that "sort of" uses ref counting, or remove ref-counting along 
entire speed critical paths. This would seem most correct at a glance.
 2. Do not render while loading. We've done this as a temporary fix, but the 
drawbacks are obvious. Heck, maybe this is not a supported feature and I have 
just somehow missed this along the way.
 3. Introduce an "UNDEFINED TIME" to initialize cache objects to when they're 
added (instead of the 0.0 that the parameter currently defaults to). This would 
allow the problem to be masked to not happen as long as the objects are 
re-ref-counted within the timeframe alotted to the object cache. I implemented 
this as well, and it works in our situation, although if I were to freeze the 
load thread long enough in the right spots I could get it to fail, implying 
it's not proper in my mind.
 4. Don't use old style OSG files. This is not really a good option for us, 
we've been using OpenSceneGraph for years, and we have a lot of customers with 
legacy OSG data out there. Our typical use has a mixture of OSG and OBJ files, 
the OBJ load paths seem to use refcounted pointers throughout.
  
I would have supplied a patch with this post, but not fully understanding the 
intentions of this code prevents me from creating something that I'm sure is 
"correct".

Build/Test Environment:
OSG 3.2, using wxWidgets 2.9.5 for windowing
Windows 8.1, 64-bit
Visual Studio 2010

Input, insight, or better solutions would be greatly appreciated.

Thanks
Baker
[/code]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=57327#57327





_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to