diff options
Diffstat (limited to 'linden/indra/llcommon/llmemory.h')
-rw-r--r-- | linden/indra/llcommon/llmemory.h | 200 |
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 | ||
37 | extern S32 gTotalDAlloc; | 35 | extern S32 gTotalDAlloc; |
38 | extern S32 gTotalDAUse; | 36 | extern 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 | ||
64 | class LLThreadSafeRefCount | 62 | // see llthread.h for LLThreadSafeRefCount |
65 | { | ||
66 | public: | ||
67 | static void initClass(); // creates sMutex | ||
68 | static void cleanupClass(); // destroys sMutex | ||
69 | |||
70 | private: | ||
71 | static LLMutex* sMutex; | ||
72 | |||
73 | private: | ||
74 | LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented | ||
75 | LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented | ||
76 | |||
77 | protected: | ||
78 | virtual ~LLThreadSafeRefCount(); // use unref() | ||
79 | |||
80 | public: | ||
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 | |||
108 | private: | ||
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 | ||
153 | template <class Type> class LLPointer | 107 | template <class Type> class LLPointer |
154 | { | 108 | { |
155 | public: | 109 | public: |
@@ -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 | |||
237 | template <class Type> | ||
238 | class LLHandle | ||
239 | { | ||
240 | public: | ||
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 | |||
329 | public: | ||
330 | typedef Type* (*NullFunc)(); | ||
331 | static const NullFunc sNullFunc; | ||
332 | |||
333 | protected: | ||
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 | |||
368 | protected: | ||
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> > |