Boost logo

Boost :

From: Phil Nash (phil.nash.lists_at_[hidden])
Date: 2002-06-25 08:03:48


> From: "Phil Nash" <phil.nash.lists_at_[hidden]>
> > Are the instrusive pointer semantics in shared_ptr being used by people
in
> > real projects yet, or is it too experimental.
>
> Yes. I use it. What library designer would refuse to use its creation? ;-)

That's reassuring - especially in view of what I will be going on to say...

> > Also, I presume that weap_ptr's are still interoperable with intrusively
> > counted shared_ptrs - is that a valid assumption?
>
> Yes.
Great, that's good to know. I have verified this for myself now, but I'm
glad its acknowledged by the author(s).

> > I would like to use it in our project, but don't want to if it is likely
> to
> > be removed, or significantly changed in the near future - or is too
> > incomplete to use. I don't mind a few issues in it that I can report
back
> on
> > to feed into development.
>
> It's fairly complete, but I can offer no guarantees about stability. (As
> with anything undocumented.)

We have decided to adopt it but I have a couple of issues with it that are
probably down to my usage. Since it's not officially part of the release
I'll ask here rather than on the boost-users list.

The problem I have is that what I have read of the thread on intrusive_ptr
and associated mods in shared_ptr led me to believe that I should be able to
provide intrusive ref counting semantics to a class in a manner that is
interoperable with shared_ptr by deriving my class from boost::counted_base
(btw, I see that counted_base has moved out of the detail namespace, but is
still located in shared_count.hpp which is in the detail sub directory. Is
this a contradiction or is that intended?).

This at first seems to be correct and compiles ok, and even begins to run
ok. I see that constructing an intrusive_ptr from a pointer to an object
derived from boost::counted_base uses the objects counted_base for its ref
counting, and I can subsequently construct a shared_ptr to the object from
the intrusive_ptr and it continues to use the object's counted_base rather
than creating its own.
However, to get this far I have to construct the counted_base with an
initial use_count (and weak_count) of 1.
The trouble comes when all intrusive_ptrs and shared_ptrs have released
their references. The use_count, of, course returns to its initial state of
1 - the object is still alive and I have to delete it manually.
Ok, I thought - to transfer ownership to the intrusive_ptr I need to call
release() immediately after constructing the intrusive_ptr (?)
Now I have a different problem. I have provided an override for the
dispose() virtual function from counted_base so that I delete myself when
the use_count gets to zero. That works ok, but counted_base also wants to
delete itself when the weak_count reaches zero. This is fine when
counted_base is the base of a different object, but we don't need (or want)
two deleters for the same object!
I want delete to be called when the use_count reaches zero, not the
weak_count - but there is no constructor for counted_base that lets me set
the deleter for the count itself. For the purposes of my investigation I
added one, and pass it a pointer to a NullDeleter function.
Trouble is the deleter function pointer is a member of counted_base, and the
call to self_deleter_() occurs *after* the call to dispose(), so during
final release the object will have been deleted before we get to
self_deleter_.
Changing the order would be wrong because if there is a self_deleter
function then that would cause the same problem the other way round! :-s

All this led me to believe that deriving from counted_base was not the way
to do it after all.
So I tried creating my own base class that aggregated shared_count, but then
I found myself still having to change boost headers to get this to work, so
I have finally reached the conclusion that I must be doing something
terribly terribly wrong here....

arrgghhh!!!!!

Please put me out of my misery :-( what is the appropriate way of using
intrusive_ptr.
One thing I haven't mentioned here is that I want to be able to create
weak_ptrs to myself in a constructor. Is that possible? (it would *seem* to
be if I can get the deletion stuff working properly).

Many thanks,

[)o
IhIL..


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