00001 /****************************************************************************** 00002 * 00003 * $Id: $ 00004 * 00005 * Copyright (C) 1997-2008 by Dimitri van Heesch. 00006 * 00007 * Permission to use, copy, modify, and distribute this software and its 00008 * documentation under the terms of the GNU General Public License is hereby 00009 * granted. No representations are made about the suitability of this software 00010 * for any purpose. It is provided "as is" without express or implied warranty. 00011 * See the GNU General Public License for more details. 00012 * 00013 * Documents produced by Doxygen are derivative works derived from the 00014 * input used in their production; they are not affected by this license. 00015 * 00016 */ 00017 00018 #ifndef LOCKINGPTR_H 00019 #define LOCKINGPTR_H 00020 00031 class LockableObj 00032 { 00033 public: 00034 LockableObj() : m_lockCount(0) {} 00035 virtual ~LockableObj() {} 00036 00038 bool isLocked() const { return m_lockCount>0; } 00039 00040 //VC++6.0 workaround 00041 // protected: 00043 virtual void lock() const = 0; 00044 00046 virtual void unlock() const = 0; 00047 00048 //VC++6.0 workaround 00049 // private: 00050 // template<class T> friend class LockingPtr; 00051 int m_lockCount; 00052 }; 00053 00062 template<class T> class LockingPtr 00063 { 00064 LockableObj *m_owner; 00065 const T *m_ptr; 00066 00067 public: 00070 LockingPtr(const LockableObj *o,const T* p) 00071 { 00072 if (o->m_lockCount==0) o->lock(); 00073 m_owner = (LockableObj *)o; 00074 m_owner->m_lockCount++; 00075 m_ptr = p; 00076 } 00077 00080 LockingPtr(const LockingPtr &lp) 00081 { 00082 m_ptr = lp.m_ptr; 00083 m_owner = lp.m_owner; 00084 m_owner->m_lockCount++; 00085 } 00086 00089 LockingPtr &operator=(const LockingPtr &lp) 00090 { 00091 m_owner->m_lockCount--; 00092 if (m_owner->m_lockCount==0) // no more references 00093 { 00094 m_owner->unlock(); 00095 } 00096 m_ptr = lp.m_ptr; 00097 m_owner = lp.m_owner; 00098 m_owner->m_lockCount++; 00099 return *this; 00100 } 00101 00104 ~LockingPtr() 00105 { 00106 m_owner->m_lockCount--; 00107 if (m_owner->m_lockCount==0) // no more references 00108 { 00109 m_owner->unlock(); 00110 } 00111 } 00112 00113 bool isNull() const 00114 { 00115 return m_ptr==0; 00116 } 00117 00118 bool operator!() const 00119 { 00120 return !m_ptr; 00121 } 00122 00123 bool operator==(T *p) const 00124 { 00125 return m_ptr==p; 00126 } 00127 00128 bool operator==(const LockingPtr &lp) const 00129 { 00130 return m_ptr==lp.m_ptr; 00131 } 00132 00133 bool operator!=(T *p) const 00134 { 00135 return m_ptr!=p; 00136 } 00137 00138 bool operator!=(const LockingPtr &lp) const 00139 { 00140 return m_ptr!=lp.m_ptr; 00141 } 00142 00144 const T& operator* () const 00145 { 00146 return *m_ptr; 00147 } 00148 00149 T* pointer() const 00150 { 00151 return (T*)m_ptr; 00152 } 00153 00155 T* operator-> () const 00156 { 00157 return (T*)m_ptr; 00158 } 00159 }; 00160 00161 #endif // LOCKINGPTR_H 00162