weak_ptr for intrusive_ptr
I greatly prefer intrusive_ptr to shared_ptr, but one drawback of that is there is no equivalent of weak_ptr. I have started work on a class to do that and my biggest question, honestly, was what to name it. The basic logic turned out to be fairly simple. The target class declares a member that is an instance of the weak pointer. Other classes that want a weak pointer to the target instance also declare a member weak pointer, which must be initialized with a copy of the target instance member. The member provides a method to generate an intrusive_ptr to the target, which is either valid or nil depending on whether the target has been destructed. When the target and all weak pointers are destructed, everything gets cleaned up. The weak pointers don't affect the target reference count. No changes to Boost.intrusive_ptr are required. The one improvement I see would be to merge it into the reference counter utility class discussed earlier (optionally, of course - perhaps via a subclass of the reference counter). Yeah, I think I'll do that. My questions: 1) What would be a good name for such a class? I am using "tell_tale" for now, in analogy to tell tale lights on devices that go out when the device fails. Obviously "weak_ptr" is out. "weak_intrusive_ptr" seems a bit verbose, but may that's OK. 2) Is there any interest in Boostifying the class, or am I the only one who would use it? It's a matter of how much I indulge my idiosyncrasies.
On Sun, Aug 10, 2008 at 9:47 AM, Alan M. Carroll
I greatly prefer intrusive_ptr to shared_ptr, but one drawback of that is there is no equivalent of weak_ptr. I have started work on a class to do that and my biggest question, honestly, was what to name it.
Have you considered the allocator support in shared_ptr? It makes it possible to allocate the control block in the same memory block as the managed object. Between this and the aliasing support in shared_ptr, I've found intrusive_ptr's use rather limited. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
Alan M. Carroll:
I greatly prefer intrusive_ptr to shared_ptr, but one drawback of that is there is no equivalent of weak_ptr. I have started work on a class to do that and my biggest question, honestly, was what to name it.
The basic logic turned out to be fairly simple. The target class declares a member that is an instance of the weak pointer. Other classes that want a weak pointer to the target instance also declare a member weak pointer, which must be initialized with a copy of the target instance member. The member provides a method to generate an intrusive_ptr to the target, which is either valid or nil depending on whether the target has been destructed. When the target and all weak pointers are destructed, everything gets cleaned up. The weak pointers don't affect the target reference count. No changes to Boost.intrusive_ptr are required.
Will you make the code available for review?
At 09:18 AM 8/14/2008, you wrote:
Alan M. Carroll:
I greatly prefer intrusive_ptr to shared_ptr, but one drawback of that is there is no equivalent of weak_ptr. I have started work on a class to do that and my biggest question, honestly, was what to name it.
Will you make the code available for review?
Yes. I have a lot of testing and Boostifcation to do before then.
Alan M. Carroll:
At 09:18 AM 8/14/2008, you wrote:
Alan M. Carroll:
I greatly prefer intrusive_ptr to shared_ptr, but one drawback of that is there is no equivalent of weak_ptr. I have started work on a class to do that and my biggest question, honestly, was what to name it.
Will you make the code available for review?
Yes. I have a lot of testing and Boostifcation to do before then.
I didn't mean a formal Boost review... just a "can we take a look at it" review.
At 08:33 AM 8/20/2008, you wrote:
I didn't mean a formal Boost review... just a "can we take a look at it" review.
Allright. I did a bit of cleanup and testing this morning and this is what I have.
Known issues:
* May not handle cross assignment of target object.
* No thread safety (not something I need, but should be thought about during Boostification)
# pragma once
// Copyright 2008 Network Geographics Inc.
// All rights reserved.
# include
Alan M. Carroll:
Known issues: * May not handle cross assignment of target object. * No thread safety (not something I need, but should be thought about during Boostification)
Thread safety is a problem. Specifically, the race where thread A drops its intrusive_ptr and thread B converts its weak pointer to an intrusive_ptr. Thread B must end up with either NULL or an intrusive_ptr to a still valid object. I'm not seeing an easy way to achieve this using your current technique of using a member or a subobject whose destructor invalidates the weak pointers since once the destructor is entered, it is too late to prevent thread B from running away with its pointer to a zombie. :-) http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/sp_techniques.html#weak_... is similar and does have the same problem, only worse. :-)
My style is such that I don't share objects between threads because of all the potential for race conditions, so I rarely design with thread safety in mind. It seems to me there are two issues: 1) From the point of view of the monitor, its pointer is reset "by surprise", an arbitrary amount of time after the object is committed to destruction. 2) The object and the reference count are destructed simultaneously. I'll look at tweaking intrusive_release_ptr, which knows before the commit to destruct that it's going to happen. Perhaps warning the monitor might work. Additionally, we can detect the existence of weak pointers before destruction by looking at the reference count of the monitor. It might help to know that as well. At 03:12 PM 8/20/2008, you wrote:
Thread safety is a problem. Specifically, the race where thread A drops its intrusive_ptr and thread B converts its weak pointer to an intrusive_ptr. Thread B must end up with either NULL or an intrusive_ptr to a still valid object. I'm not seeing an easy way to achieve this using your current technique of using a member or a subobject whose destructor invalidates the weak pointers since once the destructor is entered, it is too late to prevent thread B from running away with its pointer to a zombie. :-)
participants (4)
-
Alan M. Carroll
-
Emil Dotchevski
-
Gennadiy Rozental
-
Peter Dimov