LCOV - code coverage report
Current view: top level - DCPS - RcObject.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 107 107 100.0 %
Date: 2023-04-30 01:32:43 Functions: 82 341 24.0 %

          Line data    Source code
       1             : #ifndef OPENDDS_DCPS_RCOBJECT_H
       2             : #define OPENDDS_DCPS_RCOBJECT_H
       3             : 
       4             : #if !defined (ACE_LACKS_PRAGMA_ONCE)
       5             : # pragma once
       6             : #endif /* ACE_LACKS_PRAGMA_ONCE */
       7             : 
       8             : 
       9             : #include "dds/Versioned_Namespace.h"
      10             : 
      11             : #include "dcps_export.h"
      12             : #include "Atomic.h"
      13             : #include "PoolAllocationBase.h"
      14             : #include "RcHandle_T.h"
      15             : 
      16             : #include <ace/Guard_T.h>
      17             : #include <ace/Synch_Traits.h>
      18             : 
      19             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      20             : 
      21             : namespace OpenDDS {
      22             : namespace DCPS {
      23             : 
      24             :   class RcObject;
      25             : 
      26             :   class OpenDDS_Dcps_Export WeakObject : public PoolAllocationBase
      27             :   {
      28             :   public:
      29             : 
      30        2540 :     WeakObject(RcObject* ptr)
      31        5080 :       : ptr_(ptr)
      32        2540 :       , ref_count_(1)
      33             :     {
      34        2540 :     }
      35             : 
      36         367 :     void _add_ref()
      37             :     {
      38         367 :       ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
      39         367 :       ++ref_count_;
      40         367 :     }
      41             : 
      42        2907 :     void _remove_ref()
      43             :     {
      44        2907 :       ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
      45        2907 :       const long new_count = --ref_count_;
      46        2907 :       if (new_count == 0) {
      47        2540 :         guard.release();
      48        2540 :         delete this;
      49             :       }
      50        2907 :     }
      51             : 
      52             :     RcObject* lock();
      53             :     bool check_expire(Atomic<long>& count);
      54             : 
      55             :   private:
      56             :     mutable ACE_SYNCH_MUTEX mx_;
      57             :     RcObject* ptr_;
      58             :     long ref_count_;
      59             :   };
      60             : 
      61             :   class OpenDDS_Dcps_Export RcObject : public PoolAllocationBase {
      62             :   public:
      63             : 
      64        2540 :     virtual ~RcObject()
      65        2540 :     {
      66        2540 :       weak_object_->_remove_ref();
      67        2540 :     }
      68             : 
      69       15790 :     virtual void _add_ref()
      70             :     {
      71       15790 :       ++ref_count_;
      72       15790 :     }
      73             : 
      74       17612 :     virtual void _remove_ref()
      75             :     {
      76       17612 :       if (weak_object_->check_expire(ref_count_)) {
      77        1822 :         delete this;
      78             :       }
      79       17612 :     }
      80             : 
      81        2094 :     long ref_count() const
      82             :     {
      83        2094 :       return ref_count_;
      84             :     }
      85             : 
      86         222 :     WeakObject* _get_weak_object() const
      87             :     {
      88         222 :       weak_object_->_add_ref();
      89         222 :       return weak_object_;
      90             :     }
      91             : 
      92             :   protected:
      93        2540 :     RcObject()
      94        2540 :       : ref_count_(1)
      95        2540 :       , weak_object_(new WeakObject(this))
      96        2540 :     {}
      97             : 
      98             :   private:
      99             :     Atomic<long> ref_count_;
     100             :     WeakObject* weak_object_;
     101             : 
     102             :     RcObject(const RcObject&);
     103             :     RcObject& operator=(const RcObject&);
     104             :   };
     105             : 
     106        2141 :   inline RcObject* WeakObject::lock()
     107             :   {
     108        2141 :     ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
     109        2141 :     if (ptr_) {
     110        2138 :       ptr_->_add_ref();
     111             :     }
     112        2141 :     return ptr_;
     113        2141 :   }
     114             : 
     115       17612 :   inline bool WeakObject::check_expire(Atomic<long>& count)
     116             :   {
     117       17612 :     ACE_Guard<ACE_SYNCH_MUTEX> guard(mx_);
     118       17612 :     const long new_count = --count;
     119       17612 :     if (new_count == 0 && ptr_) {
     120        1822 :       ptr_ = 0;
     121        1822 :       return true;
     122             :     }
     123       15790 :     return false;
     124       17612 :   }
     125             : 
     126             :   template <typename T>
     127             :   class WeakRcHandle
     128             :   {
     129             :   public:
     130          17 :     WeakRcHandle()
     131          17 :       : weak_object_(0)
     132          17 :       , cached_(0)
     133             :     {
     134          17 :     }
     135             : 
     136          34 :     WeakRcHandle(const T& obj)
     137          34 :       : weak_object_(obj._get_weak_object())
     138          34 :       , cached_(const_cast<T*>(&obj))
     139             :     {
     140          34 :     }
     141             : 
     142         217 :     WeakRcHandle(const RcHandle<T>& rch)
     143         217 :       : weak_object_(rch.in() ? rch.in()->_get_weak_object() : 0)
     144         217 :       , cached_(rch.in())
     145             :     {
     146         217 :     }
     147             : 
     148         145 :     WeakRcHandle(const WeakRcHandle& other)
     149         145 :       : weak_object_(other.weak_object_)
     150         145 :       , cached_(other.cached_)
     151             :     {
     152         145 :       if (weak_object_) {
     153         145 :         weak_object_->_add_ref();
     154             :       }
     155         145 :     }
     156             : 
     157         413 :     ~WeakRcHandle()
     158             :     {
     159         413 :       if (weak_object_) {
     160         366 :         weak_object_->_remove_ref();
     161             :       }
     162         413 :     }
     163             : 
     164           1 :     WeakRcHandle& operator=(const WeakRcHandle& other)
     165             :     {
     166           1 :        WeakRcHandle tmp(other);
     167           1 :        std::swap(weak_object_, tmp.weak_object_);
     168           1 :        std::swap(cached_, tmp.cached_);
     169           1 :        return *this;
     170           1 :     }
     171             : 
     172           3 :     WeakRcHandle& operator=(const RcHandle<T>& other)
     173             :     {
     174           3 :        WeakRcHandle tmp(other);
     175           3 :        std::swap(weak_object_, tmp.weak_object_);
     176           3 :        std::swap(cached_, tmp.cached_);
     177           3 :        return *this;
     178           3 :     }
     179             : 
     180           1 :     WeakRcHandle& operator=(const T& obj)
     181             :     {
     182           1 :       WeakRcHandle tmp(obj);
     183           1 :       std::swap(weak_object_, tmp.weak_object_);
     184           1 :       std::swap(cached_, tmp.cached_);
     185           1 :       return *this;
     186           1 :     }
     187             : 
     188        2193 :     RcHandle<T> lock() const
     189             :     {
     190        2193 :       if (weak_object_ && weak_object_->lock()) {
     191        2138 :         return RcHandle<T>(cached_, keep_count());
     192             :       }
     193          55 :       return RcHandle<T>();
     194             :     }
     195             : 
     196           3 :     bool operator==(const WeakRcHandle& rhs) const
     197             :     {
     198           3 :       return weak_object_ == rhs.weak_object_;
     199             :     }
     200             : 
     201           1 :     bool operator!=(const WeakRcHandle& rhs) const
     202             :     {
     203           1 :       return weak_object_ != rhs.weak_object_;
     204             :     }
     205             : 
     206         125 :     bool operator<(const WeakRcHandle& rhs) const
     207             :     {
     208         125 :       return weak_object_ < rhs.weak_object_;
     209             :     }
     210             : 
     211           7 :     operator bool() const
     212             :     {
     213           7 :       return weak_object_;
     214             :     }
     215             : 
     216           1 :     void reset()
     217             :     {
     218           1 :       if (weak_object_) {
     219           1 :         weak_object_->_remove_ref();
     220           1 :         weak_object_ = 0;
     221             :       }
     222           1 :       cached_ = 0;
     223           1 :     }
     224             : 
     225             :   private:
     226             : 
     227             :     WeakRcHandle(WeakObject* obj)
     228             :       : weak_object_(obj)
     229             :       , cached_(dynamic_cast<T*>(obj))
     230             :     {
     231             :     }
     232             : 
     233             :     WeakObject* weak_object_;
     234             :     T* cached_;
     235             :   };
     236             : 
     237             : } // DCPS
     238             : } // OPENDDS
     239             : 
     240             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
     241             : 
     242             : #endif /* end of include guard: OPENDDS_DCPS_RCOBJECT_H */

Generated by: LCOV version 1.16