Hi J-S,
Although you plan on resubmitting this after the next release, I wanted
to make a comment now so as not to miss it later.
There's a race condition in the unref() code. The pointer passed in to
s_allocationObserver on line 213 may reference a deleted object.
Specifically, a second thread can interrupt this thread immediately
after it decrements the reference count, and unref the object to delete
it before the first thread regains control. To be safe, this call should
be moved to the top of the function, before decrementing the refCount.
Regards,
Mark
Jean-Sébastien Guay wrote:
Hi Robert,
(it might not be a good time for this, so if you want to push this
discussion to after 2.8, it's fine by me)
In light of my recent ordeal with looking for "memory leaks" (i.e.
cycles and other ref counting issues), I was wondering if you would
accept some changes to osg::Referenced which made it a bit easier to
find the source of the problem.
Just to be clear, this is more of a request for comments than a real
submission. All I'm saying is that this was useful to me, so it might
be useful to others, perhaps with some modifications.
See the attached files. It's pretty self-explanatory. Basically, if
you want you can register a callback object with osg::Referenced,
which will be called :
* when a new osg::Referenced is created
* when an osg::Referenced is destroyed
* when ref() is called on an osg::Referenced
* when unref() is called on an osg::Referenced
* when unref_nodelete() is called on an osg::Referenced
each time passing the osg::Referenced object. Then the observer can do
what it wants at any or all of these points.
In my case, I recorded a call stack to keep track of all events, and
then I could dump the events I wanted to see to a file. And since I
recorded the events in maps keyed by osg::Referenced pointer, I could
easily do differences between one state and another.
It won't do all the work for you (in my case, I had to code the part
that records the call stack which is platform- and compiler-specific,
and the parts in my application that dumped the stacks to file, and
then I had to analyse those stacks to see which objects were still
live and why) but it's a good tool I think.
Then, of course, there's the issue of performance. First of all, if
there's no registered observer, there will be one check per operation
(ctor, dtor, ref, unref, unref_nodelete). But this is only if it's
enabled in the osg::Referenced header via two #defines (which are
commented by default), one for allocation/destruction (which was
already there) and one for refs and unrefs. So you can control which
events you want to get. If these are not enabled, then there is no
performance penalty. The difference will be just one static pointer in
osg::Referenced.
So, comments? I don't think this is an exaggerated amount of code to
add, and it was certainly useful to me. But I could see how you might
argue that if no one has needed this before, it might not be generally
useful. If you agree with the principle but not the execution, please
comment and I'll try and improve the code.
Thanks,
J-S
------------------------------------------------------------------------
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org