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