summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2015-06-29 15:37:32 -0400
committerNat Goodspeed <nat@lindenlab.com>2015-06-29 15:37:32 -0400
commit76cb1fcf0b5b9d8415e2517c482bab0c6c6602fb (patch)
tree40266174a42e96d57e184b47fdfd12fd4f89d086
parent8bd39583fe19eb8f372f59f9aaee6d7c16a6f4e1 (diff)
MAINT-4952: Add IntrusivePtr wrapper for boost::intrusive_ptr.
For a RefCounted subclass T, boost::intrusive_ptr<T> must be instantiated as boost::intrusive_ptr<T>(raw ptr, false) to avoid immortal instances. Forgetting that final bool parameter is both easy and extremely hard to spot with desk checking or code review. IntrusivePtr<T> provides constructors that Do The Right Thing, so we can typedef a subclass T's ptr_t to IntrusivePtr<T> rather than directly to boost::intrusive_ptr<T>.
-rwxr-xr-xindra/llcorehttp/_refcounted.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h
index cd16e2e2b4..7f713f2298 100755
--- a/indra/llcorehttp/_refcounted.h
+++ b/indra/llcorehttp/_refcounted.h
@@ -32,6 +32,7 @@
#include "fix_macros.h"
#include <boost/thread.hpp>
+#include <boost/intrusive_ptr.hpp>
#include "llapr.h"
@@ -120,6 +121,24 @@ inline void RefCounted::destroySelf()
delete this;
}
+/**
+ * boost::intrusive_ptr may be used to manage RefCounted classes.
+ * Unfortunately RefCounted and boost::intrusive_ptr use different conventions
+ * for the initial refcount value. To avoid leaky (immortal) objects, you
+ * should really construct boost::intrusive_ptr<RefCounted*>(rawptr, false).
+ * IntrusivePtr<T> encapsulates that for you.
+ */
+template <typename T>
+struct IntrusivePtr: public boost::intrusive_ptr<T>
+{
+ IntrusivePtr():
+ boost::intrusive_ptr<T>()
+ {}
+ IntrusivePtr(T* p):
+ boost::intrusive_ptr<T>(p, false)
+ {}
+};
+
inline void intrusive_ptr_add_ref(RefCounted* p)
{
p->addRef();