RcObject.h

Go to the documentation of this file.
00001 #ifndef RCOBJECT_H_E92AD5BB
00002 #define RCOBJECT_H_E92AD5BB
00003 
00004 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00005 # pragma once
00006 #endif /* ACE_LACKS_PRAGMA_ONCE */
00007 
00008 
00009 #include "dds/Versioned_Namespace.h"
00010 #include "ace/Atomic_Op.h"
00011 #include "ace/Synch_Traits.h"
00012 #include "dds/DCPS/PoolAllocationBase.h"
00013 #include "RcHandle_T.h"
00014 
00015 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00016 
00017 namespace OpenDDS {
00018 namespace DCPS {
00019 
00020   class RcObject;
00021 
00022   class WeakObject : public PoolAllocationBase
00023   {
00024   public:
00025     WeakObject(RcObject* ptr)
00026       : ref_count_(1)
00027       , ptr_(ptr)
00028       , expired_(false)
00029     {
00030     }
00031 
00032     void _add_ref() {
00033       ++this->ref_count_;
00034     }
00035 
00036     void _remove_ref(){
00037       const long new_count = --this->ref_count_;
00038 
00039       if (new_count == 0) {
00040         delete this;
00041       }
00042     }
00043 
00044     RcObject* lock();
00045     bool set_expire();
00046   private:
00047     ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> ref_count_;
00048     ACE_SYNCH_MUTEX mx_;
00049     RcObject* const ptr_;
00050     bool expired_;
00051   };
00052 
00053   class RcObject : public PoolAllocationBase {
00054   public:
00055 
00056     virtual ~RcObject(){
00057       weak_object_->_remove_ref();
00058     }
00059 
00060     virtual void _add_ref() {
00061       ++this->ref_count_;
00062     }
00063 
00064     virtual void _remove_ref() {
00065       const long new_count = --this->ref_count_;
00066       if (new_count == 0 && weak_object_->set_expire()) {
00067         delete this;
00068       }
00069     }
00070 
00071     /// This accessor is purely for debugging purposes
00072     long ref_count() const {
00073       return this->ref_count_.value();
00074     }
00075 
00076     WeakObject*
00077     _get_weak_object() const {
00078       weak_object_->_add_ref();
00079       return weak_object_;
00080     }
00081 
00082   protected:
00083 
00084     RcObject()
00085       : ref_count_(1)
00086       , weak_object_( new WeakObject(this) )
00087     {}
00088 
00089 
00090   private:
00091 
00092     ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> ref_count_;
00093     WeakObject*  weak_object_;
00094 
00095     RcObject(const RcObject&);
00096     RcObject& operator=(const RcObject&);
00097   };
00098 
00099 
00100   inline RcObject*
00101   WeakObject::lock()
00102   {
00103     ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
00104     if (! expired_) {
00105       ptr_->_add_ref();
00106       return ptr_;
00107     }
00108     return 0;
00109   }
00110 
00111   inline bool
00112   WeakObject::set_expire()
00113   {
00114     ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
00115     if (!expired_ && ptr_->ref_count() == 0) {
00116       expired_ = true;
00117     }
00118     return expired_;
00119   }
00120 
00121   template <typename T>
00122   class WeakRcHandle
00123   {
00124   public:
00125     WeakRcHandle()
00126       : weak_object_(0)
00127     {
00128     }
00129 
00130     WeakRcHandle(const T& obj)
00131       : weak_object_(obj._get_weak_object()) {
00132     }
00133 
00134     WeakRcHandle(const RcHandle<T>& rch)
00135       : weak_object_(rch.in() ? rch.in()->_get_weak_object() : 0) {
00136     }
00137 
00138     WeakRcHandle(const WeakRcHandle& other)
00139     : weak_object_(other.weak_object_){
00140       if (weak_object_)
00141         weak_object_->_add_ref();
00142     }
00143 
00144     ~WeakRcHandle(){
00145       if (weak_object_)
00146         weak_object_->_remove_ref();
00147     }
00148 
00149     WeakRcHandle& operator = (const WeakRcHandle& other) {
00150        WeakRcHandle tmp(other);
00151        std::swap(weak_object_, tmp.weak_object_);
00152        return *this;
00153     }
00154 
00155     WeakRcHandle& operator = (const RcHandle<T>& other) {
00156        WeakRcHandle tmp(other);
00157        std::swap(weak_object_, tmp.weak_object_);
00158        return *this;
00159     }
00160 
00161     WeakRcHandle& operator = (const T& obj) {
00162       WeakRcHandle tmp(obj);
00163       std::swap(weak_object_, tmp.weak_object_);
00164       return *this;
00165     }
00166 
00167     RcHandle<T> lock() const {
00168       if (weak_object_){
00169         return RcHandle<T>(dynamic_cast<T*>(weak_object_->lock()), keep_count());
00170       }
00171       return RcHandle<T>();
00172     }
00173 
00174     bool operator==(const WeakRcHandle& rhs) const
00175     {
00176       return weak_object_ == rhs.weak_object_;
00177     }
00178 
00179     bool operator!=(const WeakRcHandle& rhs) const
00180     {
00181       return weak_object_ != rhs.weak_object_;
00182     }
00183 
00184     bool operator < (const WeakRcHandle& rhs) const
00185     {
00186       return weak_object_ < rhs.weak_object_;
00187     }
00188 
00189     operator bool() const {
00190       return weak_object_;
00191     }
00192 
00193     void reset() {
00194       if (weak_object_) {
00195         weak_object_->_remove_ref();
00196         weak_object_ = 0;
00197       }
00198     }
00199 
00200   private:
00201 
00202     WeakRcHandle(WeakObject* obj)
00203       : weak_object_(obj)
00204     {
00205     }
00206 
00207     WeakObject* weak_object_;
00208   };
00209 
00210 }// DCPS
00211 }// OPENDDS
00212 
00213 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00214 
00215 #endif /* end of include guard: RCOBJECT_H_E92AD5BB */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1