blob: 9e881c85bd811b5a32b34be7525ae3f6950cd66c [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Peter Boströmff019b02015-04-30 14:16:07 +020011#ifndef WEBRTC_BASE_REFCOUNT_H_
12#define WEBRTC_BASE_REFCOUNT_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
14#include <string.h>
sergeyuf2a1c892016-06-08 15:52:21 -070015#include <utility>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000016
Peter Boströmff019b02015-04-30 14:16:07 +020017#include "webrtc/base/atomicops.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000018
19namespace rtc {
20
21// Reference count interface.
22class RefCountInterface {
23 public:
Magnus Jedvert1b40a9a2015-10-12 15:50:43 +020024 virtual int AddRef() const = 0;
25 virtual int Release() const = 0;
sergeyuf2a1c892016-06-08 15:52:21 -070026
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000027 protected:
28 virtual ~RefCountInterface() {}
29};
30
31template <class T>
32class RefCountedObject : public T {
33 public:
sergeyuf2a1c892016-06-08 15:52:21 -070034 RefCountedObject() {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000035
sergeyuf2a1c892016-06-08 15:52:21 -070036 template <typename P>
37 explicit RefCountedObject(const P& p) : T(p) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000038
sergeyuf2a1c892016-06-08 15:52:21 -070039 template <typename P>
40 explicit RefCountedObject(P&& p) : T(std::move(p)) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000041
sergeyuf2a1c892016-06-08 15:52:21 -070042 template <typename P1, typename P2>
43 RefCountedObject(P1 p1, P2 p2) : T(p1, p2) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000044
sergeyuf2a1c892016-06-08 15:52:21 -070045 template <typename P1, typename P2, typename P3>
46 RefCountedObject(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047
sergeyuf2a1c892016-06-08 15:52:21 -070048 template <typename P1, typename P2, typename P3, typename P4>
49 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4) : T(p1, p2, p3, p4) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000050
sergeyuf2a1c892016-06-08 15:52:21 -070051 template <typename P1, typename P2, typename P3, typename P4, typename P5>
52 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) : T(p1, p2, p3, p4, p5) {}
53
54 template <typename P1,
55 typename P2,
56 typename P3,
57 typename P4,
58 typename P5,
59 typename P6>
Per33544192015-04-02 12:30:51 +020060 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
sergeyuf2a1c892016-06-08 15:52:21 -070061 : T(p1, p2, p3, p4, p5, p6) {}
Per33544192015-04-02 12:30:51 +020062
sergeyuf2a1c892016-06-08 15:52:21 -070063 template <typename P1,
64 typename P2,
65 typename P3,
66 typename P4,
67 typename P5,
68 typename P6,
69 typename P7>
Per33544192015-04-02 12:30:51 +020070 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
sergeyuf2a1c892016-06-08 15:52:21 -070071 : T(p1, p2, p3, p4, p5, p6, p7) {}
Per33544192015-04-02 12:30:51 +020072
sergeyuf2a1c892016-06-08 15:52:21 -070073 template <typename P1,
74 typename P2,
75 typename P3,
76 typename P4,
77 typename P5,
78 typename P6,
79 typename P7,
80 typename P8>
Per33544192015-04-02 12:30:51 +020081 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
sergeyuf2a1c892016-06-08 15:52:21 -070082 : T(p1, p2, p3, p4, p5, p6, p7, p8) {}
Per33544192015-04-02 12:30:51 +020083
sergeyuf2a1c892016-06-08 15:52:21 -070084 template <typename P1,
85 typename P2,
86 typename P3,
87 typename P4,
88 typename P5,
89 typename P6,
90 typename P7,
91 typename P8,
92 typename P9>
93 RefCountedObject(P1 p1,
94 P2 p2,
95 P3 p3,
96 P4 p4,
97 P5 p5,
98 P6 p6,
99 P7 p7,
100 P8 p8,
101 P9 p9)
102 : T(p1, p2, p3, p4, p5, p6, p7, p8, p9) {}
Per33544192015-04-02 12:30:51 +0200103
sergeyuf2a1c892016-06-08 15:52:21 -0700104 template <typename P1,
105 typename P2,
106 typename P3,
107 typename P4,
108 typename P5,
109 typename P6,
110 typename P7,
111 typename P8,
112 typename P9,
113 typename P10>
114 RefCountedObject(P1 p1,
115 P2 p2,
116 P3 p3,
117 P4 p4,
118 P5 p5,
119 P6 p6,
120 P7 p7,
121 P8 p8,
122 P9 p9,
123 P10 p10)
124 : T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) {}
Per33544192015-04-02 12:30:51 +0200125
sergeyuf2a1c892016-06-08 15:52:21 -0700126 template <typename P1,
127 typename P2,
128 typename P3,
129 typename P4,
130 typename P5,
131 typename P6,
132 typename P7,
133 typename P8,
134 typename P9,
135 typename P10,
136 typename P11>
137 RefCountedObject(P1 p1,
138 P2 p2,
139 P3 p3,
140 P4 p4,
141 P5 p5,
142 P6 p6,
143 P7 p7,
144 P8 p8,
145 P9 p9,
146 P10 p10,
147 P11 p11)
148 : T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) {}
Per33544192015-04-02 12:30:51 +0200149
sergeyuf2a1c892016-06-08 15:52:21 -0700150 virtual int AddRef() const { return AtomicOps::Increment(&ref_count_); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000151
Magnus Jedvertfc950842015-10-12 16:10:43 +0200152 virtual int Release() const {
pbos46ad5422015-12-07 14:29:14 -0800153 int count = AtomicOps::Decrement(&ref_count_);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000154 if (!count) {
155 delete this;
156 }
157 return count;
158 }
159
magjed@webrtc.orga43fce62015-02-21 13:23:27 +0000160 // Return whether the reference count is one. If the reference count is used
161 // in the conventional way, a reference count of 1 implies that the current
162 // thread owns the reference and no other thread shares it. This call
163 // performs the test for a reference count of one, and performs the memory
164 // barrier needed for the owning thread to act on the object, knowing that it
165 // has exclusive access to the object.
166 virtual bool HasOneRef() const {
pbos46ad5422015-12-07 14:29:14 -0800167 return AtomicOps::AcquireLoad(&ref_count_) == 1;
magjed@webrtc.orga43fce62015-02-21 13:23:27 +0000168 }
169
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000170 protected:
sergeyuf2a1c892016-06-08 15:52:21 -0700171 virtual ~RefCountedObject() {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000172
sergeyuf2a1c892016-06-08 15:52:21 -0700173 mutable volatile int ref_count_ = 0;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000174};
175
176} // namespace rtc
177
Peter Boströmff019b02015-04-30 14:16:07 +0200178#endif // WEBRTC_BASE_REFCOUNT_H_