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: 41 44 93.2 %
Date: 2026-11-09 02:10:49 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             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #ifndef SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_
       7             : #define SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_
       8             : 
       9             : #include <boost/intrusive_ptr.hpp>
      10             : 
      11             : // IntrusivePtrRef Class is an extension to boost::intrusive_ptr
      12             : // to provide additional functionality of making back reference
      13             : // pointer available with callbacks intrusive_ptr_add_back_ref
      14             : // and intrusive_ptr_del_back_ref, using which application using
      15             : // IntrusivePtrRef can keep track of pointers who holds references
      16             : // to the object
      17             : 
      18             : // referrer, pair of base pointer and member pointer
      19             : typedef std::pair<void*, void*> IntrusiveReferrer;
      20             : 
      21             : template <class D>
      22             : class IntrusivePtrRef : public boost::intrusive_ptr<D> {
      23             : public:
      24       54351 :     IntrusivePtrRef() : boost::intrusive_ptr<D>(), referrer_(NULL) {
      25       54351 :     }
      26             : 
      27       26879 :     IntrusivePtrRef(D *data) : boost::intrusive_ptr<D>(data), referrer_(NULL) {
      28       26879 :         if (data) {
      29           2 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer_, this), data);
      30             :         }
      31       26879 :     }
      32             : 
      33      214630 :     IntrusivePtrRef(D *data, void *referrer) : boost::intrusive_ptr<D>(data),
      34      214630 :                                               referrer_(referrer) {
      35      214630 :         if (data) {
      36       15142 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer, this), data);
      37             :         }
      38      214630 :     }
      39             : 
      40        3013 :     IntrusivePtrRef(IntrusivePtrRef const &rhs, void *referrer)
      41        3013 :         : boost::intrusive_ptr<D>(rhs), referrer_(referrer) {
      42        3013 :         if (this->get()) {
      43         752 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer, this),
      44         752 :                                        this->get());
      45             :         }
      46        3013 :     }
      47             : 
      48      316212 :     virtual ~IntrusivePtrRef() {
      49      316212 :         if (this->get()) {
      50       31728 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(referrer_, this), this->get());
      51             :         }
      52      632424 :     }
      53             : 
      54        1790 :     IntrusivePtrRef & operator=(IntrusivePtrRef const &rhs) {
      55        1790 :         IntrusivePtrRef(rhs, this).swap(*this);
      56        1790 :         return *this;
      57             :     }
      58             : 
      59        3499 :     IntrusivePtrRef & operator=(D *rhs) {
      60        3499 :         IntrusivePtrRef(rhs, this).swap(*this);
      61        3499 :         return *this;
      62             :     }
      63             : 
      64           0 :     void reset() {
      65           0 :         IntrusivePtrRef(NULL, this).swap(*this);
      66           0 :     }
      67             : 
      68         251 :     void reset(D *rhs) {
      69         251 :         IntrusivePtrRef(rhs, this).swap(*this);
      70         251 :     }
      71             : 
      72        5540 :     void swap(IntrusivePtrRef &rhs) {
      73             :         // Trigger Base class swap to swap values
      74        5540 :         boost::intrusive_ptr<D>::swap(rhs);
      75             : 
      76             :         // swap the referrer for this and rhs
      77        5540 :         D *tmp = this->get();
      78        5540 :         if (tmp) {
      79             :             // change referrer for new value of IntrusivePtrRef
      80        1212 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(referrer_, this), tmp);
      81        1212 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(rhs.referrer_, &rhs), tmp);
      82             :         }
      83        5540 :         tmp = rhs.get();
      84        5540 :         if (tmp) {
      85             :             // change referrer for new value of rhs
      86        2279 :             intrusive_ptr_add_back_ref(IntrusiveReferrer(rhs.referrer_, &rhs), tmp);
      87        2279 :             intrusive_ptr_del_back_ref(IntrusiveReferrer(referrer_, this), tmp);
      88             :         }
      89        5540 :     }
      90             : 
      91             : private:
      92             :     void *referrer_;
      93             : };
      94             : 
      95             : #endif  // SRC_BASE_INTRUSIVE_PTR_BACK_REF_H_

Generated by: LCOV version 1.14