LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/base - intrusive_ptr_back_ref.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 42 44 95.5 %
Date: 2026-08-24 02:06:43 Functions: 22 27 81.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_
       6             : #define SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_
       7             : 
       8             : #include <boost/intrusive_ptr.hpp>
       9             : 
      10             : // IntrusivePtrRef Class is an extension to boost::intrusive_ptr
      11             : // to provide additional functionality of making back reference
      12             : // pointer available with callbacks intrusive_ptr_add_back_ref
      13             : // and intrusive_ptr_del_back_ref, using which application using
      14             : // IntrusivePtrRef can keep track of pointers who holds references
      15             : // to the object
      16             : 
      17             : // referrer, pair of base pointer and member pointer
      18             : typedef std::pair<void*, void*> IntrusiveReferrer;
      19             : 
      20             : template <class D>
      21             : class IntrusivePtrRef : public boost::intrusive_ptr<D> {
      22             : public:
      23        7608 :     IntrusivePtrRef() : boost::intrusive_ptr<D>(), referrer_(NULL) {
      24        7608 :     }
      25             : 
      26        2713 :     IntrusivePtrRef(D *data) : boost::intrusive_ptr<D>(data), referrer_(NULL) {
      27        2713 :         if (data) {
      28           3 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer_, this), data);
      29             :         }
      30        2713 :     }
      31             : 
      32       23953 :     IntrusivePtrRef(D *data, void *referrer) : boost::intrusive_ptr<D>(data),
      33       23953 :                                               referrer_(referrer) {
      34       23953 :         if (data) {
      35        2371 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer, this), data);
      36             :         }
      37       23953 :     }
      38             : 
      39         236 :     IntrusivePtrRef(IntrusivePtrRef const &rhs, void *referrer)
      40         236 :         : boost::intrusive_ptr<D>(rhs), referrer_(referrer) {
      41         236 :         if (this->get()) {
      42           0 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer, this),
      43           0 :                                        this->get());
      44             :         }
      45         236 :     }
      46             : 
      47       37005 :     virtual ~IntrusivePtrRef() {
      48       37005 :         if (this->get()) {
      49        4547 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(referrer_, this), this->get());
      50             :         }
      51       74010 :     }
      52             : 
      53         202 :     IntrusivePtrRef & operator=(IntrusivePtrRef const &rhs) {
      54         202 :         IntrusivePtrRef(rhs, this).swap(*this);
      55         202 :         return *this;
      56             :     }
      57             : 
      58         936 :     IntrusivePtrRef & operator=(D *rhs) {
      59         936 :         IntrusivePtrRef(rhs, this).swap(*this);
      60         936 :         return *this;
      61             :     }
      62             : 
      63          10 :     void reset() {
      64          10 :         IntrusivePtrRef(NULL, this).swap(*this);
      65          10 :     }
      66             : 
      67          37 :     void reset(D *rhs) {
      68          37 :         IntrusivePtrRef(rhs, this).swap(*this);
      69          37 :     }
      70             : 
      71        1185 :     void swap(IntrusivePtrRef &rhs) {
      72             :         // Trigger Base class swap to swap values
      73        1185 :         boost::intrusive_ptr<D>::swap(rhs);
      74             : 
      75             :         // swap the referrer for this and rhs
      76        1185 :         D *tmp = this->get();
      77        1185 :         if (tmp) {
      78             :             // change referrer for new value of IntrusivePtrRef
      79         367 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer_, this), tmp);
      80         367 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(rhs.referrer_, &rhs), tmp);
      81             :         }
      82        1185 :         tmp = rhs.get();
      83        1185 :         if (tmp) {
      84             :             // change referrer for new value of rhs
      85         570 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(rhs.referrer_, &rhs), tmp);
      86         570 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(referrer_, this), tmp);
      87             :         }
      88        1185 :     }
      89             : 
      90             : private:
      91             :     void *referrer_;
      92             : };
      93             : 
      94             : #endif  // SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_

Generated by: LCOV version 1.14