Orb/Doxygen/src/lockingptr.h
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orb/Doxygen/src/lockingptr.h	Thu Jan 21 17:29:01 2010 +0000
@@ -0,0 +1,162 @@
+/******************************************************************************
+ *
+ * 
+ *
+ * Copyright (C) 1997-2008 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby 
+ * granted. No representations are made about the suitability of this software 
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef LOCKINGPTR_H
+#define LOCKINGPTR_H
+
+/*! @brief Abstract interface for lockable objects.
+ *
+ *  By implementing this interface, a smart pointer can be created which
+ *  will lock this object. This is used to prevent that an internal pointer
+ *  owned by a lockable object would become invalid when the object is removed from 
+ *  memory, leaving the client with an invalid pointer. By letting the client use 
+ *  a smart pointer instead of the real object the object will be locked into
+ *  memory until the pointer is no longer used, at which point the owner object will be
+ *  unlock and can be removed from memory.
+ */
+class LockableObj
+{
+  public:
+    LockableObj() : m_lockCount(0) {}
+    virtual ~LockableObj() {}
+
+    /*! Returns TRUE if the object is currently locked. */
+    bool isLocked() const { return m_lockCount>0; }
+
+//VC++6.0 workaround
+//  protected:
+    /*! Called when the object is locked. */
+    virtual void lock() const = 0;
+
+    /*! Called when the object is unlocked. */
+    virtual void unlock() const = 0;
+
+//VC++6.0 workaround
+//  private:
+//    template<class T> friend class LockingPtr;
+    int  m_lockCount;
+};
+
+/*! @brief Smart pointer which keeps a lock on the owner of the pointer.
+ *
+ *  With the pointer an owner object derived from LockableObj is associated.
+ *  As long as the smart object exists it will keep a lock on the obj by calling 
+ *  LockableObj::lock(). Smart pointers can be copied and passed by value. As 
+ *  soon as there or no more smart pointer references to the object, 
+ *  LockableObj::unlock() will be called automatically.
+ */
+template<class T> class LockingPtr
+{
+    LockableObj *m_owner;
+    const T *m_ptr;
+
+  public:
+    /*! Creates a smart pointer for pointer \a p owned by object \a o.
+     */
+    LockingPtr(const LockableObj *o,const T* p) 
+    { 
+      if (o->m_lockCount==0) o->lock(); 
+      m_owner = (LockableObj *)o;
+      m_owner->m_lockCount++;
+      m_ptr = p;
+    }
+    
+    /*! Copies the smart pointer \a lp 
+     */
+    LockingPtr(const LockingPtr &lp)
+    {
+      m_ptr   = lp.m_ptr;
+      m_owner = lp.m_owner;
+      m_owner->m_lockCount++;
+    }
+
+    /*! Assigns the smart pointer \a lp 
+     */
+    LockingPtr &operator=(const LockingPtr &lp)
+    {
+      m_owner->m_lockCount--;
+      if (m_owner->m_lockCount==0) // no more references
+      {
+        m_owner->unlock(); 
+      }
+      m_ptr   = lp.m_ptr;
+      m_owner = lp.m_owner;
+      m_owner->m_lockCount++;
+      return *this;
+    }
+
+    /*! Destroys the smart pointer, will unlock the owner.
+     */
+    ~LockingPtr() 
+    { 
+      m_owner->m_lockCount--;
+      if (m_owner->m_lockCount==0) // no more references
+      {
+        m_owner->unlock(); 
+      }
+    }
+
+    bool isNull() const
+    {
+      return m_ptr==0;
+    }
+
+    bool operator!() const
+    {
+      return !m_ptr;
+    }
+
+    bool operator==(T *p) const
+    {
+      return m_ptr==p;
+    }
+
+    bool operator==(const LockingPtr &lp) const
+    {
+      return m_ptr==lp.m_ptr;
+    }
+
+    bool operator!=(T *p) const
+    {
+      return m_ptr!=p;
+    }
+
+    bool operator!=(const LockingPtr &lp) const
+    {
+      return m_ptr!=lp.m_ptr;
+    }
+
+    /*! Dereference operator */
+    const T& operator* () const
+    { 
+      return *m_ptr; 
+    }
+
+    T* pointer() const
+    {
+      return (T*)m_ptr;
+    }
+    
+    /*! Pointer operator */
+    T* operator-> () const
+    { 
+      return (T*)m_ptr; 
+    }
+};
+
+#endif // LOCKINGPTR_H
+