aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llmemory.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llmemory.h')
-rw-r--r--linden/indra/llcommon/llmemory.h200
1 files changed, 151 insertions, 49 deletions
diff --git a/linden/indra/llcommon/llmemory.h b/linden/indra/llcommon/llmemory.h
index b40ab79..7a7996b 100644
--- a/linden/indra/llcommon/llmemory.h
+++ b/linden/indra/llcommon/llmemory.h
@@ -31,8 +31,6 @@
31#include <cstdlib> 31#include <cstdlib>
32 32
33#include "llerror.h" 33#include "llerror.h"
34#include "llthread.h"
35#include "llmemtype.h"
36 34
37extern S32 gTotalDAlloc; 35extern S32 gTotalDAlloc;
38extern S32 gTotalDAUse; 36extern S32 gTotalDAUse;
@@ -61,53 +59,7 @@ private:
61// LLPointer<LLFoo> x = new LLFoo; // constructor does not do anything interesting 59// LLPointer<LLFoo> x = new LLFoo; // constructor does not do anything interesting
62// x->instantiate(); // does stuff like place x into an update queue 60// x->instantiate(); // does stuff like place x into an update queue
63 61
64class LLThreadSafeRefCount 62// see llthread.h for LLThreadSafeRefCount
65{
66public:
67 static void initClass(); // creates sMutex
68 static void cleanupClass(); // destroys sMutex
69
70private:
71 static LLMutex* sMutex;
72
73private:
74 LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented
75 LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented
76
77protected:
78 virtual ~LLThreadSafeRefCount(); // use unref()
79
80public:
81 LLThreadSafeRefCount();
82
83 void ref()
84 {
85 if (sMutex) sMutex->lock();
86 mRef++;
87 if (sMutex) sMutex->unlock();
88 }
89
90 S32 unref()
91 {
92 llassert(mRef >= 1);
93 if (sMutex) sMutex->lock();
94 S32 res = --mRef;
95 if (sMutex) sMutex->unlock();
96 if (0 == res)
97 {
98 delete this;
99 res = 0;
100 }
101 return res;
102 }
103 S32 getNumRefs() const
104 {
105 return mRef;
106 }
107
108private:
109 S32 mRef;
110};
111 63
112//---------------------------------------------------------------------------- 64//----------------------------------------------------------------------------
113 65
@@ -139,6 +91,7 @@ public:
139 } 91 }
140 return mRef; 92 return mRef;
141 } 93 }
94
142 S32 getNumRefs() const 95 S32 getNumRefs() const
143 { 96 {
144 return mRef; 97 return mRef;
@@ -150,6 +103,7 @@ private:
150 103
151//---------------------------------------------------------------------------- 104//----------------------------------------------------------------------------
152 105
106// Note: relies on Type having ref() and unref() methods
153template <class Type> class LLPointer 107template <class Type> class LLPointer
154{ 108{
155public: 109public:
@@ -268,6 +222,154 @@ protected:
268 Type* mPointer; 222 Type* mPointer;
269}; 223};
270 224
225//template <class Type>
226//class LLPointerTraits
227//{
228// static Type* null();
229//};
230//
231// Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
232// This is useful in instances where operations on NULL pointers are semantically safe and/or
233// when error checking occurs at a different granularity or in a different part of the code
234// than when referencing an object via a LLHandle.
235//
236
237template <class Type>
238class LLHandle
239{
240public:
241 LLHandle() :
242 mPointer(sNullFunc())
243 {
244 ref();
245 }
246
247 LLHandle(Type* ptr) :
248 mPointer(nonNull(ptr))
249 {
250 ref();
251 }
252
253 LLHandle(const LLHandle<Type>& ptr) :
254 mPointer(ptr.mPointer)
255 {
256 ref();
257 }
258
259 // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
260 template<typename Subclass>
261 LLHandle(const LLHandle<Subclass>& ptr) :
262 mPointer(ptr.get())
263 {
264 ref();
265 }
266
267 ~LLHandle()
268 {
269 unref();
270 }
271
272 Type* get() const { return mPointer; }
273 const Type* operator->() const { return mPointer; }
274 Type* operator->() { return mPointer; }
275 const Type& operator*() const { return *mPointer; }
276 Type& operator*() { return *mPointer; }
277
278 operator BOOL() const { return (mPointer != sNullFunc()); }
279 operator bool() const { return (mPointer != sNullFunc()); }
280 bool operator!() const { return (mPointer == sNullFunc()); }
281 bool isNull() const { return (mPointer == sNullFunc()); }
282 bool notNull() const { return (mPointer != sNullFunc()); }
283
284
285 operator Type*() const { return mPointer; }
286 operator const Type*() const { return mPointer; }
287 bool operator !=(Type* ptr) const { return (mPointer != nonNull(ptr)); }
288 bool operator ==(Type* ptr) const { return (mPointer == nonNull(ptr)); }
289 bool operator ==(const LLHandle<Type>& ptr) const { return (mPointer == ptr.mPointer); }
290 bool operator < (const LLHandle<Type>& ptr) const { return (mPointer < ptr.mPointer); }
291 bool operator > (const LLHandle<Type>& ptr) const { return (mPointer > ptr.mPointer); }
292
293 LLHandle<Type>& operator =(Type* ptr)
294 {
295 if( mPointer != ptr )
296 {
297 unref();
298 mPointer = nonNull(ptr);
299 ref();
300 }
301
302 return *this;
303 }
304
305 LLHandle<Type>& operator =(const LLHandle<Type>& ptr)
306 {
307 if( mPointer != ptr.mPointer )
308 {
309 unref();
310 mPointer = ptr.mPointer;
311 ref();
312 }
313 return *this;
314 }
315
316 // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
317 template<typename Subclass>
318 LLHandle<Type>& operator =(const LLHandle<Subclass>& ptr)
319 {
320 if( mPointer != ptr.get() )
321 {
322 unref();
323 mPointer = ptr.get();
324 ref();
325 }
326 return *this;
327 }
328
329public:
330 typedef Type* (*NullFunc)();
331 static const NullFunc sNullFunc;
332
333protected:
334 void ref()
335 {
336 if (mPointer)
337 {
338 mPointer->ref();
339 }
340 }
341
342 void unref()
343 {
344 if (mPointer)
345 {
346 Type *tempp = mPointer;
347 mPointer = sNullFunc();
348 tempp->unref();
349 if (mPointer != sNullFunc())
350 {
351 llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl;
352 unref();
353 }
354 }
355 }
356
357 static Type* nonNull(Type* ptr)
358 {
359 return ptr == NULL ? sNullFunc() : ptr;
360 }
361
362 static Type* defaultNullFunc()
363 {
364 llerrs << "No null value provided for LLHandle" << llendl;
365 return NULL;
366 }
367
368protected:
369
370 Type* mPointer;
371};
372
271// LLInitializedPointer is just a pointer with a default constructor that initializes it to NULL 373// LLInitializedPointer is just a pointer with a default constructor that initializes it to NULL
272// NOT a smart pointer like LLPointer<> 374// NOT a smart pointer like LLPointer<>
273// Useful for example in std::map<int,LLInitializedPointer<LLFoo> > 375// Useful for example in std::map<int,LLInitializedPointer<LLFoo> >