Hi Robert --
 
I recently discovered that if I remove a subgraph from the scene graph
during the update traversal, most parts of that subgraph clean up (ref count
goes to zero and memory is deallocated), but not everything. In particular,
RenderLeafs in the OSG backend appear to maintain ref_ptrs to Drawables, and
perhaps other objects as well. I've found their reference counts don't drop
to zero until at least 2 frames later. I'm sure this is for efficiency
reasons, and it makes perfect sense to me why this is done, of course.
 
However, is there a way an app can force the OSG backend to flush all
ref_ptrs, so that I can be assured that OSG no longer has any references to
my subgraph?
 
I've encountered an issue on Windows, but not other operating systems. The
problem appears to be that memory allocated by a DLL gets deallocated when
the DLL is unloaded. So, for example, I might load a DLL, call into it to
create a subgraph, render for a while, then remove the subgraph. I'd like to
immediately unload the DLL at this point, but if I do, the subgraph memory
is immediately deallocated, and OSG's backend now has dangling pointers into
that memory. A crash ensues.
 
I can think of three ways to deal with this issue:
1) Instruct OSG to clear its RenderStage, RenderBin, and RenderLeaf
structures from the previous frame, thus clearing any ref_ptrs that might
still reference my subgraph. Is there a way to do this?
2) I could wait at least two frames before unloading the DLL.
3) There might be a way, when initially loading my DLL, to instruct it to
share its heap with the main process, not sure.
 
Thanks for your input,
 
Paul Martz
Skew Matrix Software LLC
http://www.skew-matrix.com <http://www.skew-matrix.com/> 
+1 303 859 9466
 
 
Bob -- Doug and I discussed this by phone last night, so this post is for
your benefit.

There are two "features" colliding here to cause this crash:

1) OSG maintains some ref_ptrs to Drawables after they've been rendered in
the draw stage, which don't get cleared until subsequent frames, probably
for efficiency reasons (no point in spending time clearing pointers that
will just be overwritten with new addresses in the next frame).

2) Windows DLLs appear to have their own heap, separate from the process
heap. When the DLL is unloaded, the DLL heap goes away.

The result: Doug's code removes a DLL-allocated subgraph from their scene
graph and immediately unloads the DLL. This causes the DLL heap to go away
(and all memory allocated on that heap). Unfortunately, OSG still has some
ref_ptrs to that memory (RenderLeafs pointing to Drawables). Those ref_ptrs
are made to point somewhere else on subsequent renderings, which causes an
unref() call into an object that has already been deallocated; badness
ensues.

Short-term workaround: wait N frames before unloading the DLL as a kind of
garbage-collection scheme. I don't know whether N is determinate or not. In
my tests, I had to wait at least 2 frames.

Long-term solution: Windows might offer a way to force a DLL to share the
heap with the process that loads the DLL. This would require further
investigation. OSG might also offer a way to flush its backend RenderLeaf
cache; I'll post to osg-users to find out.

-Paul

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to