[osg-users] CullVisitor object not getting properly deleted

Robert Osfield robert.osfield at gmail.com
Fri May 27 01:50:14 PDT 2016


Hi Rick,

Just tried, static_cast<> isn't usable in this instance thank to the
use of virtual inheritance.

So the solution I have gone for is refactor the RenderStageCache so
that it uses a map<Referenced*, ref_ptr<RenderStage>> in place of
map<CullVisitor*, ref_ptr<RenderStage>>, this means the cast happens
when the map is set up and no dynamic_cast<> need be done anywhere.

The changes are:

diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp
index d198b78..3112cdf 100644
--- a/src/osgUtil/CullVisitor.cpp
+++ b/src/osgUtil/CullVisitor.cpp
@@ -1368,7 +1368,7 @@ class RenderStageCache : public osg::Object,
public osg::Observer
 {
     public:

-        typedef std::map<CullVisitor*, osg::ref_ptr<RenderStage> >
RenderStageMap;
+        typedef std::map<osg::Referenced*, osg::ref_ptr<RenderStage>
> RenderStageMap;

         RenderStageCache() {}
         RenderStageCache(const RenderStageCache&, const osg::CopyOp&) {}
@@ -1387,18 +1387,17 @@ class RenderStageCache : public osg::Object,
public osg::Observer
         virtual void objectDeleted(void* object)
         {
             osg::Referenced* ref = reinterpret_cast<osg::Referenced*>(object);
-            osgUtil::CullVisitor* cv =
dynamic_cast<osgUtil::CullVisitor*>(ref);

             OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

-            RenderStageMap::iterator itr = _renderStageMap.find(cv);
+            RenderStageMap::iterator itr = _renderStageMap.find(ref);
             if (itr!=_renderStageMap.end())
             {
                 _renderStageMap.erase(itr);
             }
         }

-        void setRenderStage(CullVisitor* cv, RenderStage* rs)
+        void setRenderStage(osg::Referenced* cv, RenderStage* rs)
         {
             OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
             RenderStageMap::iterator itr = _renderStageMap.find(cv);
@@ -1414,7 +1413,7 @@ class RenderStageCache : public osg::Object,
public osg::Observer

         }

-        RenderStage* getRenderStage(osgUtil::CullVisitor* cv)
+        RenderStage* getRenderStage(osg::Referenced* cv)
         {
             OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
             RenderStageMap::iterator itr = _renderStageMap.find(cv);


I have checked this fix into OSG master and 3.4 branch.  Commit is
110cf56..31592d2

Could you let me know how this works out, if it fails I'm afraid I'll
need a small test example to reproduce it as the osgoi and
osgprerender examples I'm using are working 100% OK.

Robert.

On 27 May 2016 at 09:01, Robert Osfield <robert.osfield at gmail.com> wrote:
> Hi Rick,
>
> As general note, use of a C pointer to scene graph objects include the
> CullVisitor should generally be avoided, it's only safe for small
> blocks of code where you know that the objects will remain in memory
> at all times during the block.  Instead you should use ref_ptr<> to
> make sure it's lifetime is correct - if in doubt use ref_ptr<>.
>
> I will have a look at the use of dynamic_cast<> again.  I had to keep
> it in there because the pointer to the Referenced base class isn't
> castable directly to a CullVsititor as CullVisitor uses virtual
> inheritance.
>
> Robert.
>
>
> On 26 May 2016 at 22:04, Rick Irons <Rick.Irons at mathworks.com> wrote:
>> Hi Robert,
>>
>>
>>
>> Unfortunately the fix didn't address the crash I am encountering.  The issue
>> of the dynamic cast in objectDeleted()
>> (\openscenegraph\src\osgUtil\CullVisitor.cpp) failing remains...
>>
>>
>>
>>         virtual void objectDeleted(void* object)
>>
>>         {
>>
>>             osg::Referenced* ref =
>> reinterpret_cast<osg::Referenced*>(object);
>>
>>             osgUtil::CullVisitor* cv =
>> dynamic_cast<osgUtil::CullVisitor*>(ref);
>>
>>
>>
>>             OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
>>
>>
>>
>>             RenderStageMap::iterator itr = _renderStageMap.find(cv);
>>
>>             if (itr!=_renderStageMap.end())
>>
>>             {
>>
>>                 _renderStageMap.erase(itr);
>>
>>             }
>>
>>         }
>>
>>
>>
>> I was going to define our object that inherits from the CullVisitor as an
>> osg::ref_ptr.  Perhaps doing so will delay the freeing of the CullVisitor
>> object long enough within the CullVisitor destructor so that the problematic
>> dynamic cast will succeed.  I am open to any other suggestions as well.  I
>> may have to resort to just creating a small example program that reproduces
>> the issue.
>>
>>
>>
>> Thanks,
>>
>> Rick
>>
>>
>>
>> -----Original Message-----
>> From: Rick Irons
>> Sent: Wednesday, May 25, 2016 5:56 AM
>> To: OpenSceneGraph Users <osg-users at lists.openscenegraph.org>
>> Subject: Re: [osg-users] CullVisitor object not getting properly deleted
>>
>>
>>
>> Hi Robert,
>>
>>
>>
>> Thanks for the update.   I will try out the fix.
>>
>>
>>
>> Rick
>>
>>
>>
>>> On May 24, 2016, at 3:53 PM, Robert Osfield <robert.osfield at gmail.com>
>>> wrote:
>>
>>>
>>
>>> Hi Rick,
>>
>>>
>>
>>> After a preplexing day looking at how the osgUtiil::CullVisitor,
>>
>>> osg::Camera and RenderStageCache were all interacting via the
>>
>>> osg::Observer system I finally fixed the problem with the crash that
>>
>>> I've see with the osgoit and osgprerender examples.   As the crash
>>
>>> looks similar to what you saw there is reasonable chance that the
>>
>>> changes should work for you too.
>>
>>>
>>
>>> I have checked my fix into master and OpenSceneGraph-3.4.
>>
>>>
>>
>>> Robert.
>>
>>> _______________________________________________
>>
>>> osg-users mailing list
>>
>>> osg-users at lists.openscenegraph.org
>>
>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.
>>
>>> org
>>
>>
>> _______________________________________________
>> osg-users mailing list
>> osg-users at lists.openscenegraph.org
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>



More information about the osg-users mailing list