Orb/Doxygen/src/lockingptr.h
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 #ifndef LOCKINGPTR_H
       
    19 #define LOCKINGPTR_H
       
    20 
       
    21 /*! @brief Abstract interface for lockable objects.
       
    22  *
       
    23  *  By implementing this interface, a smart pointer can be created which
       
    24  *  will lock this object. This is used to prevent that an internal pointer
       
    25  *  owned by a lockable object would become invalid when the object is removed from 
       
    26  *  memory, leaving the client with an invalid pointer. By letting the client use 
       
    27  *  a smart pointer instead of the real object the object will be locked into
       
    28  *  memory until the pointer is no longer used, at which point the owner object will be
       
    29  *  unlock and can be removed from memory.
       
    30  */
       
    31 class LockableObj
       
    32 {
       
    33   public:
       
    34     LockableObj() : m_lockCount(0) {}
       
    35     virtual ~LockableObj() {}
       
    36 
       
    37     /*! Returns TRUE if the object is currently locked. */
       
    38     bool isLocked() const { return m_lockCount>0; }
       
    39 
       
    40 //VC++6.0 workaround
       
    41 //  protected:
       
    42     /*! Called when the object is locked. */
       
    43     virtual void lock() const = 0;
       
    44 
       
    45     /*! Called when the object is unlocked. */
       
    46     virtual void unlock() const = 0;
       
    47 
       
    48 //VC++6.0 workaround
       
    49 //  private:
       
    50 //    template<class T> friend class LockingPtr;
       
    51     int  m_lockCount;
       
    52 };
       
    53 
       
    54 /*! @brief Smart pointer which keeps a lock on the owner of the pointer.
       
    55  *
       
    56  *  With the pointer an owner object derived from LockableObj is associated.
       
    57  *  As long as the smart object exists it will keep a lock on the obj by calling 
       
    58  *  LockableObj::lock(). Smart pointers can be copied and passed by value. As 
       
    59  *  soon as there or no more smart pointer references to the object, 
       
    60  *  LockableObj::unlock() will be called automatically.
       
    61  */
       
    62 template<class T> class LockingPtr
       
    63 {
       
    64     LockableObj *m_owner;
       
    65     const T *m_ptr;
       
    66 
       
    67   public:
       
    68     /*! Creates a smart pointer for pointer \a p owned by object \a o.
       
    69      */
       
    70     LockingPtr(const LockableObj *o,const T* p) 
       
    71     { 
       
    72       if (o->m_lockCount==0) o->lock(); 
       
    73       m_owner = (LockableObj *)o;
       
    74       m_owner->m_lockCount++;
       
    75       m_ptr = p;
       
    76     }
       
    77     
       
    78     /*! Copies the smart pointer \a lp 
       
    79      */
       
    80     LockingPtr(const LockingPtr &lp)
       
    81     {
       
    82       m_ptr   = lp.m_ptr;
       
    83       m_owner = lp.m_owner;
       
    84       m_owner->m_lockCount++;
       
    85     }
       
    86 
       
    87     /*! Assigns the smart pointer \a lp 
       
    88      */
       
    89     LockingPtr &operator=(const LockingPtr &lp)
       
    90     {
       
    91       m_owner->m_lockCount--;
       
    92       if (m_owner->m_lockCount==0) // no more references
       
    93       {
       
    94         m_owner->unlock(); 
       
    95       }
       
    96       m_ptr   = lp.m_ptr;
       
    97       m_owner = lp.m_owner;
       
    98       m_owner->m_lockCount++;
       
    99       return *this;
       
   100     }
       
   101 
       
   102     /*! Destroys the smart pointer, will unlock the owner.
       
   103      */
       
   104     ~LockingPtr() 
       
   105     { 
       
   106       m_owner->m_lockCount--;
       
   107       if (m_owner->m_lockCount==0) // no more references
       
   108       {
       
   109         m_owner->unlock(); 
       
   110       }
       
   111     }
       
   112 
       
   113     bool isNull() const
       
   114     {
       
   115       return m_ptr==0;
       
   116     }
       
   117 
       
   118     bool operator!() const
       
   119     {
       
   120       return !m_ptr;
       
   121     }
       
   122 
       
   123     bool operator==(T *p) const
       
   124     {
       
   125       return m_ptr==p;
       
   126     }
       
   127 
       
   128     bool operator==(const LockingPtr &lp) const
       
   129     {
       
   130       return m_ptr==lp.m_ptr;
       
   131     }
       
   132 
       
   133     bool operator!=(T *p) const
       
   134     {
       
   135       return m_ptr!=p;
       
   136     }
       
   137 
       
   138     bool operator!=(const LockingPtr &lp) const
       
   139     {
       
   140       return m_ptr!=lp.m_ptr;
       
   141     }
       
   142 
       
   143     /*! Dereference operator */
       
   144     const T& operator* () const
       
   145     { 
       
   146       return *m_ptr; 
       
   147     }
       
   148 
       
   149     T* pointer() const
       
   150     {
       
   151       return (T*)m_ptr;
       
   152     }
       
   153     
       
   154     /*! Pointer operator */
       
   155     T* operator-> () const
       
   156     { 
       
   157       return (T*)m_ptr; 
       
   158     }
       
   159 };
       
   160 
       
   161 #endif // LOCKINGPTR_H
       
   162