1 /* 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 11 #ifndef WEBRTC_BASE_REFCOUNT_H_ 12 #define WEBRTC_BASE_REFCOUNT_H_ 13 14 #include <string.h> 15 16 #include "webrtc/base/atomicops.h" 17 18 namespace rtc { 19 20 // Reference count interface. 21 class RefCountInterface { 22 public: 23 virtual int AddRef() const = 0; 24 virtual int Release() const = 0; 25 protected: ~RefCountInterface()26 virtual ~RefCountInterface() {} 27 }; 28 29 template <class T> 30 class RefCountedObject : public T { 31 public: RefCountedObject()32 RefCountedObject() : ref_count_(0) { 33 } 34 35 template<typename P> RefCountedObject(P p)36 explicit RefCountedObject(P p) : T(p), ref_count_(0) { 37 } 38 39 template<typename P1, typename P2> RefCountedObject(P1 p1,P2 p2)40 RefCountedObject(P1 p1, P2 p2) : T(p1, p2), ref_count_(0) { 41 } 42 43 template<typename P1, typename P2, typename P3> RefCountedObject(P1 p1,P2 p2,P3 p3)44 RefCountedObject(P1 p1, P2 p2, P3 p3) : T(p1, p2, p3), ref_count_(0) { 45 } 46 47 template<typename P1, typename P2, typename P3, typename P4> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4)48 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4) 49 : T(p1, p2, p3, p4), ref_count_(0) { 50 } 51 52 template<typename P1, typename P2, typename P3, typename P4, typename P5> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)53 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 54 : T(p1, p2, p3, p4, p5), ref_count_(0) { 55 } 56 57 template<typename P1, typename P2, typename P3, typename P4, typename P5, 58 typename P6> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6)59 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 60 : T(p1, p2, p3, p4, p5, p6), ref_count_(0) { 61 } 62 63 template<typename P1, typename P2, typename P3, typename P4, typename P5, 64 typename P6, typename P7> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6,P7 p7)65 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) 66 : T(p1, p2, p3, p4, p5, p6, p7), ref_count_(0) { 67 } 68 69 template<typename P1, typename P2, typename P3, typename P4, typename P5, 70 typename P6, typename P7, typename P8> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6,P7 p7,P8 p8)71 RefCountedObject(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) 72 : T(p1, p2, p3, p4, p5, p6, p7, p8), ref_count_(0) { 73 } 74 75 template<typename P1, typename P2, typename P3, typename P4, typename P5, 76 typename P6, typename P7, typename P8, typename P9> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6,P7 p7,P8 p8,P9 p9)77 RefCountedObject( 78 P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) 79 : T(p1, p2, p3, p4, p5, p6, p7, p8, p9), ref_count_(0) { 80 } 81 82 template<typename P1, typename P2, typename P3, typename P4, typename P5, 83 typename P6, typename P7, typename P8, typename P9, typename P10> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6,P7 p7,P8 p8,P9 p9,P10 p10)84 RefCountedObject( 85 P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) 86 : T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10), ref_count_(0) { 87 } 88 89 template<typename P1, typename P2, typename P3, typename P4, typename P5, 90 typename P6, typename P7, typename P8, typename P9, typename P10, 91 typename P11> RefCountedObject(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5,P6 p6,P7 p7,P8 p8,P9 p9,P10 p10,P11 p11)92 RefCountedObject( 93 P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, 94 P11 p11) 95 : T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11), ref_count_(0) { 96 } 97 AddRef()98 virtual int AddRef() const { 99 return AtomicOps::Increment(&ref_count_); 100 } 101 Release()102 virtual int Release() const { 103 int count = AtomicOps::Decrement(&ref_count_); 104 if (!count) { 105 delete this; 106 } 107 return count; 108 } 109 110 // Return whether the reference count is one. If the reference count is used 111 // in the conventional way, a reference count of 1 implies that the current 112 // thread owns the reference and no other thread shares it. This call 113 // performs the test for a reference count of one, and performs the memory 114 // barrier needed for the owning thread to act on the object, knowing that it 115 // has exclusive access to the object. HasOneRef()116 virtual bool HasOneRef() const { 117 return AtomicOps::AcquireLoad(&ref_count_) == 1; 118 } 119 120 protected: ~RefCountedObject()121 virtual ~RefCountedObject() { 122 } 123 124 mutable volatile int ref_count_; 125 }; 126 127 } // namespace rtc 128 129 #endif // WEBRTC_BASE_REFCOUNT_H_ 130