views:

124

answers:

2

Hi,

For legacy reasons I need to use intrusive pointers, as I need the ability to convert raw pointers to smart pointers.

However I noticed there is no weak intrusive pointer for boost. I did find a talk about it on the boost thread list, however nothing concrete.

Does anyone know of a thread safe implementation of weak intrusive pointer?

Thanks Rich

+2  A: 

Current implementation of intrusive pointer is using reference counter. So deleting object delete also delete the counter, so weak_intrusive_pointer will never know that the object was deleted.

If you need to get weak_ptr from this, you probably search boost::enable_shared_from_this<T>.

lionbest
+5  A: 

It does not make any sense.

To elaborate: weak_ptr points to the same instance of a counter object that shared_ptr do. When the shared_ptr goes out of scope, the instance of the counter stays (with a count effectively at 0), which allows the weak_ptr instances to check that they effectively point to a freed object.

With Intrusive Counting, the counter is integrated within the object. When the count reaches 0, the object is usually either recycled or deleted... but the point is the counter is no longer available. The rationale is that this allow for a more efficient storage (1 single chunk) and greater speed (cache locality).

If you need Weak Reference counting and do not care for the benefits of intrusive counting, you can use a combination of shared_ptr and weak_ptr.

The idea is to deassociate the counter from the objects.

class Counted
{
  // bla
private:
  boost::shared_ptr<int> mCounter;
};

Now you can return weak handles:

class WeakHandle
{
public:
  explicit WeakHandle(Counted& c): mCounter(c.mCounter), mObject(&c) {}

  bool expired() const { return mCounter.expired(); }

private:
  boost::weak_ptr<int> mCounter;
  Counted* mObject;
};

Here, we deassociate the lifetime of the counter from the lifetime of the object, so that it will survive the destruction of the object... partially. Thus making the weak_ptr effectively possible.

And of course, using shared_ptr and weak_ptr this is Thread Safe ;)

Matthieu M.
My idea is to embed the shared object used by shared ptr and weak ptr inside of the host object and intrusive_weak_ptr (if that existed) would use it the same way as weak_ptr does. I still need the functionality of deleting the object when there are no more references. In addition I need to take weak references.
Rich
I think you did not understand my point: that is exactly what I propose. The `Counted` object is "intrusively" counted, I just changed the counter from a plain integer to a pointer to an integer. As for your `intrusive_weak_ptr` that's just what I called `WeakHandle`.
Matthieu M.
Ah I think I'm with you. So I'd use an intrusive pointer as normal, however when intrusive_ptr_add_ref is called, I reference the int from the shared pointer as my count. When that hits zero the object is freed, however any weak references maintain a pointer to the int. Is that correct?
Rich
Clever, I like it, thank you.
Rich
Yes that's it, you're welcome :)
Matthieu M.