00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2006 Torus Knot Software Ltd 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 00024 You may alternatively use this source under the terms of a specific version of 00025 the OGRE Unrestricted License provided you have obtained such a license from 00026 Torus Knot Software Ltd. 00027 ----------------------------------------------------------------------------- 00028 */ 00029 #ifndef __SharedPtr_H__ 00030 #define __SharedPtr_H__ 00031 00032 #include "OgrePrerequisites.h" 00033 00034 namespace Ogre { 00035 00044 template<class T> class SharedPtr { 00045 protected: 00046 T* pRep; 00047 unsigned int* pUseCount; 00048 public: 00049 OGRE_AUTO_SHARED_MUTEX // public to allow external locking 00054 SharedPtr() : pRep(0), pUseCount(0) 00055 { 00056 OGRE_SET_AUTO_SHARED_MUTEX_NULL 00057 } 00058 00059 template< class Y> 00060 explicit SharedPtr(Y* rep) : pRep(rep), pUseCount(new unsigned int(1)) 00061 { 00062 OGRE_SET_AUTO_SHARED_MUTEX_NULL 00063 OGRE_NEW_AUTO_SHARED_MUTEX 00064 } 00065 SharedPtr(const SharedPtr& r) 00066 : pRep(0), pUseCount(0) 00067 { 00068 // lock & copy other mutex pointer 00069 00070 OGRE_SET_AUTO_SHARED_MUTEX_NULL 00071 OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME) 00072 { 00073 OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) 00074 OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) 00075 pRep = r.pRep; 00076 pUseCount = r.pUseCount; 00077 // Handle zero pointer gracefully to manage STL containers 00078 if(pUseCount) 00079 { 00080 ++(*pUseCount); 00081 } 00082 } 00083 } 00084 SharedPtr& operator=(const SharedPtr& r) { 00085 if (pRep == r.pRep) 00086 return *this; 00087 // Swap current data into a local copy 00088 // this ensures we deal with rhs and this being dependent 00089 SharedPtr<T> tmp(r); 00090 swap(tmp); 00091 return *this; 00092 } 00093 00094 template< class Y> 00095 SharedPtr(const SharedPtr<Y>& r) 00096 : pRep(0), pUseCount(0) 00097 { 00098 // lock & copy other mutex pointer 00099 00100 OGRE_SET_AUTO_SHARED_MUTEX_NULL 00101 OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME) 00102 { 00103 OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) 00104 OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) 00105 pRep = r.getPointer(); 00106 pUseCount = r.useCountPointer(); 00107 // Handle zero pointer gracefully to manage STL containers 00108 if(pUseCount) 00109 { 00110 ++(*pUseCount); 00111 } 00112 } 00113 } 00114 template< class Y> 00115 SharedPtr& operator=(const SharedPtr<Y>& r) { 00116 if (pRep == r.pRep) 00117 return *this; 00118 // Swap current data into a local copy 00119 // this ensures we deal with rhs and this being dependent 00120 SharedPtr<T> tmp(r); 00121 swap(tmp); 00122 return *this; 00123 } 00124 virtual ~SharedPtr() { 00125 release(); 00126 } 00127 00128 00129 inline T& operator*() const { assert(pRep); return *pRep; } 00130 inline T* operator->() const { assert(pRep); return pRep; } 00131 inline T* get() const { return pRep; } 00132 00137 void bind(T* rep) { 00138 assert(!pRep && !pUseCount); 00139 OGRE_NEW_AUTO_SHARED_MUTEX 00140 OGRE_LOCK_AUTO_SHARED_MUTEX 00141 pUseCount = new unsigned int(1); 00142 pRep = rep; 00143 } 00144 00145 inline bool unique() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount == 1; } 00146 inline unsigned int useCount() const { OGRE_LOCK_AUTO_SHARED_MUTEX assert(pUseCount); return *pUseCount; } 00147 inline unsigned int* useCountPointer() const { return pUseCount; } 00148 00149 inline T* getPointer() const { return pRep; } 00150 00151 inline bool isNull(void) const { return pRep == 0; } 00152 00153 inline void setNull(void) { 00154 if (pRep) 00155 { 00156 // can't scope lock mutex before release incase deleted 00157 release(); 00158 pRep = 0; 00159 pUseCount = 0; 00160 } 00161 } 00162 00163 protected: 00164 00165 inline void release(void) 00166 { 00167 bool destroyThis = false; 00168 00169 /* If the mutex is not initialized to a non-zero value, then 00170 neither is pUseCount nor pRep. 00171 */ 00172 00173 OGRE_MUTEX_CONDITIONAL(OGRE_AUTO_MUTEX_NAME) 00174 { 00175 // lock own mutex in limited scope (must unlock before destroy) 00176 OGRE_LOCK_AUTO_SHARED_MUTEX 00177 if (pUseCount) 00178 { 00179 if (--(*pUseCount) == 0) 00180 { 00181 destroyThis = true; 00182 } 00183 } 00184 } 00185 if (destroyThis) 00186 destroy(); 00187 00188 OGRE_SET_AUTO_SHARED_MUTEX_NULL 00189 } 00190 00191 virtual void destroy(void) 00192 { 00193 // IF YOU GET A CRASH HERE, YOU FORGOT TO FREE UP POINTERS 00194 // BEFORE SHUTTING OGRE DOWN 00195 // Use setNull() before shutdown or make sure your pointer goes 00196 // out of scope before OGRE shuts down to avoid this. 00197 delete pRep; 00198 delete pUseCount; 00199 OGRE_DELETE_AUTO_SHARED_MUTEX 00200 } 00201 00202 virtual void swap(SharedPtr<T> &other) 00203 { 00204 std::swap(pRep, other.pRep); 00205 std::swap(pUseCount, other.pUseCount); 00206 #if OGRE_THREAD_SUPPORT 00207 std::swap(OGRE_AUTO_MUTEX_NAME, other.OGRE_AUTO_MUTEX_NAME); 00208 #endif 00209 } 00210 }; 00211 00212 template<class T, class U> inline bool operator==(SharedPtr<T> const& a, SharedPtr<U> const& b) 00213 { 00214 return a.get() == b.get(); 00215 } 00216 00217 template<class T, class U> inline bool operator!=(SharedPtr<T> const& a, SharedPtr<U> const& b) 00218 { 00219 return a.get() != b.get(); 00220 } 00221 } 00222 00223 00224 00225 #endif
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Mon Jun 16 12:48:56 2008