RcObject_T.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef OPENDDS_RCOBJECT_T_H
00009 #define OPENDDS_RCOBJECT_T_H
00010 
00011 #include "dds/DCPS/dcps_export.h"
00012 #include "ace/Atomic_Op.h"
00013 #include "ace/Malloc_Base.h"
00014 #include "dds/DCPS/PoolAllocationBase.h"
00015 
00016 namespace OpenDDS {
00017 namespace DCPS {
00018 
00019 /// Templated reference counting mix-in.
00020 /// A non-DDS specific helper class.
00021 /// The T type is an ace lock type
00022 /// (eg, ACE_SYNCH_MUTEX, ACE_NULL_MUTEX, etc...)
00023 template <typename T>
00024   class OpenDDS_Dcps_Export RcObject : public PoolAllocationBase {
00025 public:
00026 
00027   virtual ~RcObject() {}
00028 
00029   virtual void _add_ref() {
00030     ++this->ref_count_;
00031   }
00032 
00033   virtual void _remove_ref() {
00034     long new_count = --this->ref_count_;
00035 
00036     if (new_count == 0) {
00037       // No need to protect the allocator with a lock since this
00038       // is the last reference to this object, and thus only one
00039       // thread will be doing this final _remove_ref().
00040       ACE_Allocator* allocator = this->allocator_;
00041       this->allocator_ = 0;
00042 
00043       if (allocator) {
00044         this->~RcObject();
00045         allocator->free(this);
00046       } else {
00047         delete this;
00048       }
00049     }
00050   }
00051 
00052   /// This accessor is purely for debugging purposes
00053   long ref_count() const {
00054     return this->ref_count_.value();
00055   }
00056 
00057 protected:
00058 
00059   RcObject(ACE_Allocator* allocator = 0)
00060     : ref_count_(1), allocator_(allocator)
00061   {}
00062 
00063 private:
00064 
00065   ACE_Atomic_Op<T, long> ref_count_;
00066   ACE_Allocator*         allocator_;
00067 
00068   // Turning these off.  I don't think they should be used for
00069   // objects that would be reference counted.  Maybe a copy_from()
00070   // method instead (if needed).
00071   RcObject(const RcObject&);
00072   RcObject& operator=(const RcObject&);
00073 };
00074 
00075 } // namespace DCPS
00076 } // namespace OpenDDS
00077 
00078 #endif  /*OPENDDS_RCOBJECT_T_H */

Generated on Fri Feb 12 20:05:25 2016 for OpenDDS by  doxygen 1.4.7