• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _DESHAREDPTR_HPP
2 #define _DESHAREDPTR_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements C++ Base Library
5  * -----------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Shared pointer.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "deDefs.hpp"
27 #include "deAtomic.h"
28 
29 #include <exception>
30 #include <algorithm>
31 
32 namespace de
33 {
34 
35 //! Shared pointer self-test.
36 void SharedPtr_selfTest (void);
37 
38 class DeadReferenceException : public std::exception
39 {
40 public:
DeadReferenceException(void)41 	DeadReferenceException (void) throw() : std::exception() {}
what(void) const42 	const char* what (void) const throw() { return "DeadReferenceException"; }
43 };
44 
45 template<bool threadSafe>
46 struct ReferenceCount;
47 
48 template<> struct ReferenceCount<true>	{ typedef volatile int	Type; };
49 template<> struct ReferenceCount<false>	{ typedef int			Type; };
50 
51 template<class Deleter, bool threadSafe>
52 struct SharedPtrState
53 {
SharedPtrStatede::SharedPtrState54 	SharedPtrState (Deleter deleter_)
55 		: strongRefCount	(0)
56 		, weakRefCount		(0)
57 		, deleter			(deleter_)
58 	{
59 	}
60 
61 	typename ReferenceCount<threadSafe>::Type	strongRefCount;
62 	typename ReferenceCount<threadSafe>::Type	weakRefCount;		//!< WeakPtr references + StrongPtr references.
63 	Deleter										deleter;
64 };
65 
66 template<typename DstDeleterType, typename SrcDeleterType, bool threadSafe>
sharedPtrStateCast(SharedPtrState<SrcDeleterType,threadSafe> * state)67 SharedPtrState<DstDeleterType, threadSafe>* sharedPtrStateCast (SharedPtrState<SrcDeleterType, threadSafe>* state)
68 {
69 	return reinterpret_cast<SharedPtrState<DstDeleterType, threadSafe>*>(state);
70 }
71 
72 template<typename T, class Deleter, bool threadSafe>
73 class SharedPtr;
74 
75 template<typename T, class Deleter, bool threadSafe>
76 class WeakPtr;
77 
78 /*--------------------------------------------------------------------*//*!
79  * \brief Shared pointer
80  *
81  * SharedPtr is smart pointer for managing shared ownership to a pointer.
82  * Multiple SharedPtr's can maintain ownership to the pointer and it is
83  * destructed when last SharedPtr is destroyed.
84  *
85  * Shared pointers can be assigned (or initialized using copy constructor)
86  * and in such case the previous reference is first freed and then a new
87  * reference to the new pointer is acquired.
88  *
89  * SharedPtr can also be empty.
90  *
91  * If threadSafe template parameter is set to true, it is safe to share
92  * data using SharedPtr across threads. SharedPtr object itself is not
93  * thread safe and should not be mutated from multiple threads simultaneously.
94  *
95  * \todo [2012-10-26 pyry] Add custom deleter.
96  *//*--------------------------------------------------------------------*/
97 template<typename T, class Deleter = DefaultDeleter<T>, bool threadSafe = true>
98 class SharedPtr
99 {
100 public:
101 								SharedPtr			(void);
102 								SharedPtr			(const SharedPtr<T, Deleter, threadSafe>& other);
103 
104 	template<typename Y>
105 	explicit					SharedPtr			(Y* ptr, Deleter deleter = Deleter());
106 
107 	template<typename Y, class DeleterY>
108 	explicit					SharedPtr			(const SharedPtr<Y, DeleterY, threadSafe>& other);
109 
110 	template<typename Y, class DeleterY>
111 	explicit					SharedPtr			(const WeakPtr<Y, DeleterY, threadSafe>& other);
112 
113 								~SharedPtr			(void);
114 
115 	template<typename Y, class DeleterY>
116 	SharedPtr&					operator=			(const SharedPtr<Y, DeleterY, threadSafe>& other);
117 	SharedPtr&					operator=			(const SharedPtr<T, Deleter, threadSafe>& other);
118 
119 	template<typename Y, class DeleterY>
120 	SharedPtr&					operator=			(const WeakPtr<Y, DeleterY, threadSafe>& other);
121 
get(void) const122 	T*							get					(void) const throw() { return m_ptr;	}	//!< Get stored pointer.
operator ->(void) const123 	T*							operator->			(void) const throw() { return m_ptr;	}	//!< Get stored pointer.
operator *(void) const124 	T&							operator*			(void) const throw() { return *m_ptr;	}	//!< De-reference pointer.
125 
operator bool(void) const126 	operator					bool				(void) const throw() { return !!m_ptr;	}
127 
128 	void						swap				(SharedPtr<T, Deleter, threadSafe>& other);
129 
130 	void						clear				(void);
131 
132 	template<typename Y, class DeleterY>
133 	operator SharedPtr<Y, DeleterY, threadSafe>	(void) const;
134 
135 private:
136 	void						acquire				(void);
137 	void						acquireFromWeak		(const WeakPtr<T, Deleter, threadSafe>& other);
138 	void						release				(void);
139 
140 	T*												m_ptr;
141 	SharedPtrState<Deleter, threadSafe>*			m_state;
142 
143 	friend class WeakPtr<T, Deleter, threadSafe>;
144 
145 	template<typename U, class DeleterU, bool threadSafeU>
146 	friend class SharedPtr;
147 };
148 
149 /*--------------------------------------------------------------------*//*!
150  * \brief Weak pointer
151  *
152  * WeakPtr manages weak references to objects owned by SharedPtr. Shared
153  * pointer can be converted to weak pointer and vice versa. Weak pointer
154  * differs from SharedPtr by not affecting the lifetime of the managed
155  * object.
156  *
157  * WeakPtr can be converted back to SharedPtr but that operation can fail
158  * if the object is no longer live. In such case DeadReferenceException
159  * will be thrown.
160  *
161  * \todo [2012-10-26 pyry] Add custom deleter.
162  *//*--------------------------------------------------------------------*/
163 template<typename T, class Deleter = DefaultDeleter<T>, bool threadSafe = true>
164 class WeakPtr
165 {
166 public:
167 						WeakPtr				(void);
168 						WeakPtr				(const WeakPtr<T, Deleter, threadSafe>& other);
169 	explicit			WeakPtr				(const SharedPtr<T, Deleter, threadSafe>& other);
170 						~WeakPtr			(void);
171 
172 	WeakPtr&			operator=			(const WeakPtr<T, Deleter, threadSafe>& other);
173 	WeakPtr&			operator=			(const SharedPtr<T, Deleter, threadSafe>& other);
174 
175 	SharedPtr<T, Deleter, threadSafe>	lock	(void);
176 
177 private:
178 	void				acquire				(void);
179 	void				release				(void);
180 
181 	T*										m_ptr;
182 	SharedPtrState<Deleter, threadSafe>*	m_state;
183 
184 	friend class SharedPtr<T, Deleter, threadSafe>;
185 };
186 
187 // SharedPtr template implementation.
188 
189 /*--------------------------------------------------------------------*//*!
190  * \brief Construct empty shared pointer.
191  *//*--------------------------------------------------------------------*/
192 template<typename T, class Deleter, bool threadSafe>
SharedPtr(void)193 inline SharedPtr<T, Deleter, threadSafe>::SharedPtr (void)
194 	: m_ptr		(DE_NULL)
195 	, m_state	(DE_NULL)
196 {
197 }
198 
199 /*--------------------------------------------------------------------*//*!
200  * \brief Construct shared pointer from pointer.
201  * \param ptr Pointer to be managed.
202  *
203  * Ownership of the pointer will be transferred to SharedPtr and future
204  * SharedPtr's initialized or assigned from this SharedPtr.
205  *
206  * Y* must be convertible to T*.
207  *//*--------------------------------------------------------------------*/
208 template<typename T, class Deleter, bool threadSafe>
209 template<typename Y>
SharedPtr(Y * ptr,Deleter deleter)210 inline SharedPtr<T, Deleter, threadSafe>::SharedPtr (Y* ptr, Deleter deleter)
211 	: m_ptr		(DE_NULL)
212 	, m_state	(DE_NULL)
213 {
214 	try
215 	{
216 		m_ptr	= ptr;
217 		m_state	= new SharedPtrState<Deleter, threadSafe>(deleter);
218 		m_state->strongRefCount	= 1;
219 		m_state->weakRefCount	= 1;
220 	}
221 	catch (...)
222 	{
223 		delete m_ptr;
224 		delete m_state;
225 		throw;
226 	}
227 }
228 
229 /*--------------------------------------------------------------------*//*!
230  * \brief Initialize shared pointer from another SharedPtr.
231  * \param other Pointer to be shared.
232  *//*--------------------------------------------------------------------*/
233 template<typename T, class Deleter, bool threadSafe>
SharedPtr(const SharedPtr<T,Deleter,threadSafe> & other)234 inline SharedPtr<T, Deleter, threadSafe>::SharedPtr (const SharedPtr<T, Deleter, threadSafe>& other)
235 	: m_ptr		(other.m_ptr)
236 	, m_state	(other.m_state)
237 {
238 	acquire();
239 }
240 
241 /*--------------------------------------------------------------------*//*!
242  * \brief Initialize shared pointer from another SharedPtr.
243  * \param other Pointer to be shared.
244  *
245  * Y* must be convertible to T*.
246  *//*--------------------------------------------------------------------*/
247 template<typename T, class Deleter, bool threadSafe>
248 template<typename Y, class DeleterY>
SharedPtr(const SharedPtr<Y,DeleterY,threadSafe> & other)249 inline SharedPtr<T, Deleter, threadSafe>::SharedPtr (const SharedPtr<Y, DeleterY, threadSafe>& other)
250 	: m_ptr		(other.m_ptr)
251 	, m_state	(sharedPtrStateCast<Deleter>(other.m_state))
252 {
253 	acquire();
254 }
255 
256 /*--------------------------------------------------------------------*//*!
257  * \brief Initialize shared pointer from weak reference.
258  * \param other Pointer to be shared.
259  *
260  * Y* must be convertible to T*.
261  *//*--------------------------------------------------------------------*/
262 template<typename T, class Deleter, bool threadSafe>
263 template<typename Y, class DeleterY>
SharedPtr(const WeakPtr<Y,DeleterY,threadSafe> & other)264 inline SharedPtr<T, Deleter, threadSafe>::SharedPtr (const WeakPtr<Y, DeleterY, threadSafe>& other)
265 	: m_ptr		(DE_NULL)
266 	, m_state	(DE_NULL)
267 {
268 	acquireFromWeak(other);
269 }
270 
271 template<typename T, class Deleter, bool threadSafe>
~SharedPtr(void)272 inline SharedPtr<T, Deleter, threadSafe>::~SharedPtr (void)
273 {
274 	release();
275 }
276 
277 /*--------------------------------------------------------------------*//*!
278  * \brief Assign from other shared pointer.
279  * \param other Pointer to be shared.
280  * \return Reference to this SharedPtr.
281  *
282  * Reference to current pointer (if any) will be released first. Then a new
283  * reference to the pointer managed by other will be acquired.
284  *
285  * Y* must be convertible to T*.
286  *//*--------------------------------------------------------------------*/
287 template<typename T, class Deleter, bool threadSafe>
288 template<typename Y, class DeleterY>
operator =(const SharedPtr<Y,DeleterY,threadSafe> & other)289 inline SharedPtr<T, Deleter, threadSafe>& SharedPtr<T, Deleter, threadSafe>::operator= (const SharedPtr<Y, DeleterY, threadSafe>& other)
290 {
291 	if (*this == other)
292 		return *this;
293 
294 	// Release current reference.
295 	release();
296 
297 	// Copy from other and acquire reference.
298 	m_ptr	= other.m_ptr;
299 	m_state	= sharedPtrStateCast<Deleter>(other.m_state);
300 
301 	acquire();
302 
303 	return *this;
304 }
305 
306 /*--------------------------------------------------------------------*//*!
307  * \brief Assign from other shared pointer.
308  * \param other Pointer to be shared.
309  * \return Reference to this SharedPtr.
310  *
311  * Reference to current pointer (if any) will be released first. Then a new
312  * reference to the pointer managed by other will be acquired.
313  *//*--------------------------------------------------------------------*/
314 template<typename T, class Deleter, bool threadSafe>
operator =(const SharedPtr<T,Deleter,threadSafe> & other)315 inline SharedPtr<T, Deleter, threadSafe>& SharedPtr<T, Deleter, threadSafe>::operator= (const SharedPtr<T, Deleter, threadSafe>& other)
316 {
317 	if (*this == other)
318 		return *this;
319 
320 	// Release current reference.
321 	release();
322 
323 	// Copy from other and acquire reference.
324 	m_ptr	= other.m_ptr;
325 	m_state	= other.m_state;
326 
327 	acquire();
328 
329 	return *this;
330 }
331 
332 /*--------------------------------------------------------------------*//*!
333  * \brief Assign from weak pointer.
334  * \param other Weak reference.
335  * \return Reference to this SharedPtr.
336  *
337  * Reference to current pointer (if any) will be released first. Then a
338  * reference to pointer managed by WeakPtr is acquired if the pointer
339  * is still live (eg. there's at least one strong reference).
340  *
341  * If pointer is no longer live, DeadReferenceException is thrown.
342  *
343  * Y* must be convertible to T*.
344  *//*--------------------------------------------------------------------*/
345 template<typename T, class Deleter, bool threadSafe>
346 template<typename Y, class DeleterY>
operator =(const WeakPtr<Y,DeleterY,threadSafe> & other)347 inline SharedPtr<T, Deleter, threadSafe>& SharedPtr<T, Deleter, threadSafe>::operator= (const WeakPtr<Y, DeleterY, threadSafe>& other)
348 {
349 	// Release current reference.
350 	release();
351 
352 	m_ptr	= DE_NULL;
353 	m_state	= DE_NULL;
354 
355 	acquireFromWeak(other);
356 
357 	return *this;
358 }
359 
360 /*--------------------------------------------------------------------*//*!
361  * \brief Type conversion operator.
362  *
363  * T* must be convertible to Y*. Since resulting SharedPtr will share the
364  * ownership destroying Y* must be equal to destroying T*.
365  *//*--------------------------------------------------------------------*/
366 template<class T, class Deleter, bool threadSafe>
367 template<typename Y, class DeleterY>
operator SharedPtr<Y,DeleterY,threadSafe>(void) const368 inline SharedPtr<T, Deleter, threadSafe>::operator SharedPtr<Y, DeleterY, threadSafe> (void) const
369 {
370 	return SharedPtr<Y, DeleterY, threadSafe>(*this);
371 }
372 
373 /*--------------------------------------------------------------------*//*!
374  * \brief Compare pointers.
375  * \param a A
376  * \param b B
377  * \return true if A and B point to same object, false otherwise.
378  *//*--------------------------------------------------------------------*/
379 template<class T, class DeleterT, bool threadSafeT, class U, class DeleterU, bool threadSafeU>
operator ==(const SharedPtr<T,DeleterT,threadSafeT> & a,const SharedPtr<U,DeleterU,threadSafeU> & b)380 inline bool operator== (const SharedPtr<T, DeleterT, threadSafeT>& a, const SharedPtr<U, DeleterU, threadSafeU>& b) throw()
381 {
382 	return a.get() == b.get();
383 }
384 
385 /*--------------------------------------------------------------------*//*!
386  * \brief Compare pointers.
387  * \param a A
388  * \param b B
389  * \return true if A and B point to different objects, false otherwise.
390  *//*--------------------------------------------------------------------*/
391 template<class T, class DeleterT, bool threadSafeT, class U, class DeleterU, bool threadSafeU>
operator !=(const SharedPtr<T,DeleterT,threadSafeT> & a,const SharedPtr<U,DeleterU,threadSafeU> & b)392 inline bool operator!= (const SharedPtr<T, DeleterT, threadSafeT>& a, const SharedPtr<U, DeleterU, threadSafeU>& b) throw()
393 {
394 	return a.get() != b.get();
395 }
396 
397 /** Swap pointer contents. */
398 template<typename T, class Deleter, bool threadSafe>
swap(SharedPtr<T,Deleter,threadSafe> & other)399 inline void SharedPtr<T, Deleter, threadSafe>::swap (SharedPtr<T, Deleter, threadSafe>& other)
400 {
401 	using std::swap;
402 	swap(m_ptr,		other.m_ptr);
403 	swap(m_state,	other.m_state);
404 }
405 
406 /** Swap operator for SharedPtr's. */
407 template<typename T, class Deleter, bool threadSafe>
swap(SharedPtr<T,Deleter,threadSafe> & a,SharedPtr<T,Deleter,threadSafe> & b)408 inline void swap (SharedPtr<T, Deleter, threadSafe>& a, SharedPtr<T, Deleter, threadSafe>& b)
409 {
410 	a.swap(b);
411 }
412 
413 /*--------------------------------------------------------------------*//*!
414  * \brief Set pointer to null.
415  *
416  * clear() removes current reference and sets pointer to null value.
417  *//*--------------------------------------------------------------------*/
418 template<typename T, class Deleter, bool threadSafe>
clear(void)419 inline void SharedPtr<T, Deleter, threadSafe>::clear (void)
420 {
421 	release();
422 	m_ptr	= DE_NULL;
423 	m_state	= DE_NULL;
424 }
425 
426 template<typename T, class Deleter, bool threadSafe>
acquireFromWeak(const WeakPtr<T,Deleter,threadSafe> & weakRef)427 inline void SharedPtr<T, Deleter, threadSafe>::acquireFromWeak (const WeakPtr<T, Deleter, threadSafe>& weakRef)
428 {
429 	DE_ASSERT(!m_ptr && !m_state);
430 
431 	SharedPtrState<Deleter, threadSafe>* state = weakRef.m_state;
432 
433 	if (!state)
434 		return; // Empty reference.
435 
436 	if (threadSafe)
437 	{
438 		int oldCount, newCount;
439 
440 		// Do atomic compare and increment.
441 		do
442 		{
443 			oldCount = state->strongRefCount;
444 			if (oldCount == 0)
445 				throw DeadReferenceException();
446 			newCount = oldCount+1;
447 		} while (deAtomicCompareExchange32((deUint32 volatile*)&state->strongRefCount, (deUint32)oldCount, (deUint32)newCount) != (deUint32)oldCount);
448 
449 		deAtomicIncrement32(&state->weakRefCount);
450 	}
451 	else
452 	{
453 		if (state->strongRefCount == 0)
454 			throw DeadReferenceException();
455 
456 		state->strongRefCount	+= 1;
457 		state->weakRefCount		+= 1;
458 	}
459 
460 	m_ptr	= weakRef.m_ptr;
461 	m_state	= state;
462 }
463 
464 template<typename T, class Deleter, bool threadSafe>
acquire(void)465 inline void SharedPtr<T, Deleter, threadSafe>::acquire (void)
466 {
467 	if (m_state)
468 	{
469 		if (threadSafe)
470 		{
471 			deAtomicIncrement32((deInt32 volatile*)&m_state->strongRefCount);
472 			deAtomicIncrement32((deInt32 volatile*)&m_state->weakRefCount);
473 		}
474 		else
475 		{
476 			m_state->strongRefCount	+= 1;
477 			m_state->weakRefCount	+= 1;
478 		}
479 	}
480 }
481 
482 template<typename T, class Deleter, bool threadSafe>
release(void)483 inline void SharedPtr<T, Deleter, threadSafe>::release (void)
484 {
485 	if (m_state)
486 	{
487 		if (threadSafe)
488 		{
489 			if (deAtomicDecrement32(&m_state->strongRefCount) == 0)
490 			{
491 				m_state->deleter(m_ptr);
492 				m_ptr = DE_NULL;
493 			}
494 
495 			if (deAtomicDecrement32(&m_state->weakRefCount) == 0)
496 			{
497 				delete m_state;
498 				m_state = DE_NULL;
499 			}
500 		}
501 		else
502 		{
503 			m_state->strongRefCount	-= 1;
504 			m_state->weakRefCount	-= 1;
505 			DE_ASSERT(m_state->strongRefCount >= 0 && m_state->weakRefCount >= 0);
506 
507 			if (m_state->strongRefCount == 0)
508 			{
509 				m_state->deleter(m_ptr);
510 				m_ptr = DE_NULL;
511 			}
512 
513 			if (m_state->weakRefCount == 0)
514 			{
515 				delete m_state;
516 				m_state = DE_NULL;
517 			}
518 		}
519 	}
520 }
521 
522 // WeakPtr template implementation.
523 
524 /*--------------------------------------------------------------------*//*!
525  * \brief Construct empty weak pointer.
526  *//*--------------------------------------------------------------------*/
527 template<typename T, class Deleter, bool threadSafe>
WeakPtr(void)528 inline WeakPtr<T, Deleter, threadSafe>::WeakPtr (void)
529 	: m_ptr		(DE_NULL)
530 	, m_state	(DE_NULL)
531 {
532 }
533 
534 /*--------------------------------------------------------------------*//*!
535  * \brief Construct weak pointer from other weak reference.
536  * \param other Weak reference.
537  *//*--------------------------------------------------------------------*/
538 template<typename T, class Deleter, bool threadSafe>
WeakPtr(const WeakPtr<T,Deleter,threadSafe> & other)539 inline WeakPtr<T, Deleter, threadSafe>::WeakPtr (const WeakPtr<T, Deleter, threadSafe>& other)
540 	: m_ptr		(other.m_ptr)
541 	, m_state	(other.m_state)
542 {
543 	acquire();
544 }
545 
546 /*--------------------------------------------------------------------*//*!
547  * \brief Construct weak pointer from shared pointer.
548  * \param other Shared pointer.
549  *//*--------------------------------------------------------------------*/
550 template<typename T, class Deleter, bool threadSafe>
WeakPtr(const SharedPtr<T,Deleter,threadSafe> & other)551 inline WeakPtr<T, Deleter, threadSafe>::WeakPtr (const SharedPtr<T, Deleter, threadSafe>& other)
552 	: m_ptr		(other.m_ptr)
553 	, m_state	(other.m_state)
554 {
555 	acquire();
556 }
557 
558 template<typename T, class Deleter, bool threadSafe>
~WeakPtr(void)559 inline WeakPtr<T, Deleter, threadSafe>::~WeakPtr (void)
560 {
561 	release();
562 }
563 
564 /*--------------------------------------------------------------------*//*!
565  * \brief Assign from another weak pointer.
566  * \param other Weak reference.
567  * \return Reference to this WeakPtr.
568  *
569  * The current weak reference is removed first and then a new weak reference
570  * to the object pointed by other is taken.
571  *//*--------------------------------------------------------------------*/
572 template<typename T, class Deleter, bool threadSafe>
operator =(const WeakPtr<T,Deleter,threadSafe> & other)573 inline WeakPtr<T, Deleter, threadSafe>& WeakPtr<T, Deleter, threadSafe>::operator= (const WeakPtr<T, Deleter, threadSafe>& other)
574 {
575 	if (this == &other)
576 		return *this;
577 
578 	release();
579 
580 	m_ptr	= other.m_ptr;
581 	m_state	= other.m_state;
582 
583 	acquire();
584 
585 	return *this;
586 }
587 
588 /*--------------------------------------------------------------------*//*!
589  * \brief Assign from shared pointer.
590  * \param other Shared pointer.
591  * \return Reference to this WeakPtr.
592  *
593  * The current weak reference is removed first and then a new weak reference
594  * to the object pointed by other is taken.
595  *//*--------------------------------------------------------------------*/
596 template<typename T, class Deleter, bool threadSafe>
operator =(const SharedPtr<T,Deleter,threadSafe> & other)597 inline WeakPtr<T, Deleter, threadSafe>& WeakPtr<T, Deleter, threadSafe>::operator= (const SharedPtr<T, Deleter, threadSafe>& other)
598 {
599 	release();
600 
601 	m_ptr	= other.m_ptr;
602 	m_state	= other.m_state;
603 
604 	acquire();
605 
606 	return *this;
607 }
608 
609 template<typename T, class Deleter, bool threadSafe>
acquire(void)610 inline void WeakPtr<T, Deleter, threadSafe>::acquire (void)
611 {
612 	if (m_state)
613 	{
614 		if (threadSafe)
615 			deAtomicIncrement32(&m_state->weakRefCount);
616 		else
617 			m_state->weakRefCount += 1;
618 	}
619 }
620 
621 template<typename T, class Deleter, bool threadSafe>
release(void)622 inline void WeakPtr<T, Deleter, threadSafe>::release (void)
623 {
624 	if (m_state)
625 	{
626 		if (threadSafe)
627 		{
628 			if (deAtomicDecrement32(&m_state->weakRefCount) == 0)
629 			{
630 				delete m_state;
631 				m_state	= DE_NULL;
632 				m_ptr	= DE_NULL;
633 			}
634 		}
635 		else
636 		{
637 			m_state->weakRefCount -= 1;
638 			DE_ASSERT(m_state->weakRefCount >= 0);
639 
640 			if (m_state->weakRefCount == 0)
641 			{
642 				delete m_state;
643 				m_state	= DE_NULL;
644 				m_ptr	= DE_NULL;
645 			}
646 		}
647 	}
648 }
649 
650 } // de
651 
652 #endif // _DESHAREDPTR_HPP
653