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: 39 44 88.6 %
Date: 2026-08-03 02:19:58 Functions: 21 27 77.8 %
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        2778 :     IntrusivePtrRef() : boost::intrusive_ptr<D>(), referrer_(NULL) {
      24        2778 :     }
      25             : 
      26        1156 :     IntrusivePtrRef(D *data) : boost::intrusive_ptr<D>(data), referrer_(NULL) {
      27        1156 :         if (data) {
      28           3 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer_, this), data);
      29             :         }
      30        1156 :     }
      31             : 
      32        9463 :     IntrusivePtrRef(D *data, void *referrer) : boost::intrusive_ptr<D>(data),
      33        9463 :                                               referrer_(referrer) {
      34        9463 :         if (data) {
      35         713 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer, this), data);
      36             :         }
      37        9463 :     }
      38             : 
      39          60 :     IntrusivePtrRef(IntrusivePtrRef const &rhs, void *referrer)
      40          60 :         : boost::intrusive_ptr<D>(rhs), referrer_(referrer) {
      41          60 :         if (this->get()) {
      42           0 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer, this),
      43           0 :                                        this->get());
      44             :         }
      45          60 :     }
      46             : 
      47       14776 :     virtual ~IntrusivePtrRef() {
      48       14776 :         if (this->get()) {
      49        1893 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(referrer_, this), this->get());
      50             :         }
      51       29552 :     }
      52             : 
      53          46 :     IntrusivePtrRef & operator=(IntrusivePtrRef const &rhs) {
      54          46 :         IntrusivePtrRef(rhs, this).swap(*this);
      55          46 :         return *this;
      56             :     }
      57             : 
      58         394 :     IntrusivePtrRef & operator=(D *rhs) {
      59         394 :         IntrusivePtrRef(rhs, this).swap(*this);
      60         394 :         return *this;
      61             :     }
      62             : 
      63           0 :     void reset() {
      64           0 :         IntrusivePtrRef(NULL, this).swap(*this);
      65           0 :     }
      66             : 
      67          12 :     void reset(D *rhs) {
      68          12 :         IntrusivePtrRef(rhs, this).swap(*this);
      69          12 :     }
      70             : 
      71         452 :     void swap(IntrusivePtrRef &rhs) {
      72             :         // Trigger Base class swap to swap values
      73         452 :         boost::intrusive_ptr<D>::swap(rhs);
      74             : 
      75             :         // swap the referrer for this and rhs
      76         452 :         D *tmp = this->get();
      77         452 :         if (tmp) {
      78             :             // change referrer for new value of IntrusivePtrRef
      79         144 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer_, this), tmp);
      80         144 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(rhs.referrer_, &rhs), tmp);
      81             :         }
      82         452 :         tmp = rhs.get();
      83         452 :         if (tmp) {
      84             :             // change referrer for new value of rhs
      85         249 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(rhs.referrer_, &rhs), tmp);
      86         249 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(referrer_, this), tmp);
      87             :         }
      88         452 :     }
      89             : 
      90             : private:
      91             :     void *referrer_;
      92             : };
      93             : 
      94             : #endif  // SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_

Generated by: LCOV version 1.14