]>
Commit | Line | Data |
---|---|---|
1077c1b8 | 1 | /* |
5b74111a | 2 | * Copyright (C) 1996-2018 The Squid Software Foundation and contributors |
1077c1b8 | 3 | * |
bbc27441 AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
1077c1b8 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section -- Refcount allocator */ |
10 | ||
605f2c3e AJ |
11 | #ifndef SQUID_REFCOUNT_H_ |
12 | #define SQUID_REFCOUNT_H_ | |
1077c1b8 | 13 | |
8bf217bd AJ |
14 | // reference counting requires the Lock API on base classes |
15 | #include "base/Lock.h" | |
16 | ||
7c36d157 | 17 | #include <iostream> |
18 | ||
8bf217bd AJ |
19 | /** |
20 | * Template for Reference Counting pointers. | |
21 | * | |
2763a37c | 22 | * Objects of type 'C' must inherit from 'RefCountable' in base/Lock.h |
8bf217bd AJ |
23 | * which provides the locking interface used by reference counting. |
24 | */ | |
1077c1b8 | 25 | template <class C> |
43ae1d95 | 26 | class RefCount |
27 | { | |
28 | ||
1077c1b8 | 29 | public: |
43ae1d95 | 30 | RefCount () : p_ (NULL) {} |
31 | ||
32 | RefCount (C const *p) : p_(p) { reference (*this); } | |
33 | ||
c5dd4956 | 34 | ~RefCount() { |
43ae1d95 | 35 | dereference(); |
1077c1b8 | 36 | } |
43ae1d95 | 37 | |
c5dd4956 | 38 | RefCount (const RefCount &p) : p_(p.p_) { |
43ae1d95 | 39 | reference (p); |
1077c1b8 | 40 | } |
43ae1d95 | 41 | |
47349075 FC |
42 | RefCount (RefCount &&p) : p_(std::move(p.p_)) { |
43 | p.p_=NULL; | |
44 | } | |
45 | ||
c5dd4956 | 46 | RefCount& operator = (const RefCount& p) { |
43ae1d95 | 47 | // DO NOT CHANGE THE ORDER HERE!!! |
48 | // This preserves semantics on self assignment | |
49 | C const *newP_ = p.p_; | |
50 | reference(p); | |
db812f89 | 51 | dereference(newP_); |
43ae1d95 | 52 | return *this; |
1077c1b8 | 53 | } |
43ae1d95 | 54 | |
47349075 | 55 | RefCount& operator = (RefCount&& p) { |
5a0d1f98 | 56 | if (this != &p) { |
0e63f973 | 57 | dereference(p.p_); |
5a0d1f98 FC |
58 | p.p_ = NULL; |
59 | } | |
29d97824 | 60 | return *this; |
47349075 FC |
61 | } |
62 | ||
95426d2e AR |
63 | explicit operator bool() const { return p_; } |
64 | ||
c5dd4956 | 65 | bool operator !() const { return !p_; } |
be702f78 | 66 | |
b0d53123 | 67 | C * operator-> () const {return const_cast<C *>(p_); } |
43ae1d95 | 68 | |
801cfc26 CT |
69 | C & operator * () const { |
70 | assert(p_); | |
71 | return *const_cast<C *>(p_); | |
72 | } | |
43ae1d95 | 73 | |
801cfc26 | 74 | C * getRaw() const { return const_cast<C *>(p_); } |
43ae1d95 | 75 | |
c5dd4956 | 76 | bool operator == (const RefCount& p) const { |
43ae1d95 | 77 | return p.p_ == p_; |
1077c1b8 | 78 | } |
43ae1d95 | 79 | |
c5dd4956 | 80 | bool operator != (const RefCount &p) const { |
0655fa4d | 81 | return p.p_ != p_; |
82 | } | |
83 | ||
1077c1b8 | 84 | private: |
c5dd4956 | 85 | void dereference(C const *newP = NULL) { |
db812f89 | 86 | /* Setting p_ first is important: |
00d77d6b | 87 | * we may be freed ourselves as a result of |
88 | * delete p_; | |
89 | */ | |
faffe22c | 90 | C const (*tempP_) (p_); |
00d77d6b | 91 | p_ = newP; |
92 | ||
8bf217bd | 93 | if (tempP_ && tempP_->unlock() == 0) |
00d77d6b | 94 | delete tempP_; |
1077c1b8 | 95 | } |
43ae1d95 | 96 | |
c5dd4956 | 97 | void reference (const RefCount& p) { |
43ae1d95 | 98 | if (p.p_) |
8bf217bd | 99 | p.p_->lock(); |
1077c1b8 | 100 | } |
43ae1d95 | 101 | |
102 | C const *p_; | |
1077c1b8 | 103 | |
104 | }; | |
105 | ||
7c36d157 | 106 | template <class C> |
107 | inline std::ostream &operator <<(std::ostream &os, const RefCount<C> &p) | |
108 | { | |
109 | if (p != NULL) | |
8bf217bd | 110 | return os << p.getRaw() << '*' << p->LockCount(); |
7c36d157 | 111 | else |
112 | return os << "NULL"; | |
113 | } | |
114 | ||
605f2c3e | 115 | #endif /* SQUID_REFCOUNT_H_ */ |
f53969cc | 116 |