Boost logo

Boost :

From: Larry Evans (jcampbell3_at_[hidden])
Date: 2003-01-07 17:20:48


Peter Dimov wrote:
> From: "William E. Kempf" <wekempf_at_[hidden]>
>
>>I don't follow this. How does the user prevent the destructors from
>
> referencing the other
>
>>object(s) participating in the cycle which may no longer exist? The only
>
> safe way to break
>
>>the cycle is to have intimate knowledge about the objects participating in
>
> the cycle and do
>
>>what ever clean up is required in a determistic manner *before* the
>
> object's are destroyed
>
>>and the memory is freed.
>
>
> (please use line wrapping)
>
> Consider the original example:
>
> struct X
> {
> boost::shared_ptr<X> p;
> };
>
> int main()
> {
> boost::shared_ptr<X> p1(new X);
> boost::shared_ptr<X> p2(new X);
>
> p1->p = p2;
> p2->p = p1;
>
> p1.reset();
> p2.reset();
>
> break_cycles();
> }
>
> Here is what break_cycles would do:
An alternative is to modify the cyclic_count_gc_local_mark_scan.hpp
file I uploaded to the shared_cyclic_ptr directory on about 9/21/02.
This modifcation would not only restore the refcounts for the live object
but also, or almost also, for the dead ones. Whenever the restoration
encounters a cycle (it could keep track via some mark on the object
indicating it was earlier visted on the stack) it would zero the pointer and
not add the 1, thus breaking the cycle. Then it would delete the original
arg to local_mark_scan (since if any objects are deleted, this one has to be
one of them), and everything would work fine. That is, everything work
work fine except you wouldn't know which node in the cycle is the first one
to be an argument to local_mark_scan.

I haven't tested any of this, but so far I can't see a flaw (except for the
uncertainty about the which is the first delete in the cycle).

>
> 1. Find the two X objects (let's call them x1 and x2) on the heap, and scan
Wouldn't this scan have to be either conservative, like BW, or use some way
to determine the precise location of the shared_ptr's within, .e.g. p1->get()?
This some way could be, for example, that used in the shared_cyclic_ptr
directory.

This scan will also have to follow plain pointers. In order to do that
precisely using smart pointers and the method in shared_cyclic_ptr, you'd have
to use another type of smart pointer, e.g. scoped_uncollected_ptr, which only
records its offset in the containing subject, like shared_cyclic_ptr does
in the files/shared_cyclic_ptr directory.

I'm working on this now. I could post it, but it's incomplete. I could use
some feedback though. It's uses a "bridge_iterator" instead of the function
stack, cyclic_count_ip_base::graph_traverser_base::m_visit_parent_stk in
cyclic_count_ip_base.hpp. Because of this, it should be easier to understand.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk