lockingptr.h

Go to the documentation of this file.
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 



Generated on Mon Mar 31 10:58:40 2008 by  doxygen 1.5.1