1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2017 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker #ifndef API_REF_COUNTED_BASE_H_ 11*d9f75844SAndroid Build Coastguard Worker #define API_REF_COUNTED_BASE_H_ 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker #include <type_traits> 14*d9f75844SAndroid Build Coastguard Worker 15*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ref_counter.h" 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker namespace rtc { 18*d9f75844SAndroid Build Coastguard Worker 19*d9f75844SAndroid Build Coastguard Worker class RefCountedBase { 20*d9f75844SAndroid Build Coastguard Worker public: 21*d9f75844SAndroid Build Coastguard Worker RefCountedBase() = default; 22*d9f75844SAndroid Build Coastguard Worker 23*d9f75844SAndroid Build Coastguard Worker RefCountedBase(const RefCountedBase&) = delete; 24*d9f75844SAndroid Build Coastguard Worker RefCountedBase& operator=(const RefCountedBase&) = delete; 25*d9f75844SAndroid Build Coastguard Worker AddRef()26*d9f75844SAndroid Build Coastguard Worker void AddRef() const { ref_count_.IncRef(); } Release()27*d9f75844SAndroid Build Coastguard Worker RefCountReleaseStatus Release() const { 28*d9f75844SAndroid Build Coastguard Worker const auto status = ref_count_.DecRef(); 29*d9f75844SAndroid Build Coastguard Worker if (status == RefCountReleaseStatus::kDroppedLastRef) { 30*d9f75844SAndroid Build Coastguard Worker delete this; 31*d9f75844SAndroid Build Coastguard Worker } 32*d9f75844SAndroid Build Coastguard Worker return status; 33*d9f75844SAndroid Build Coastguard Worker } 34*d9f75844SAndroid Build Coastguard Worker 35*d9f75844SAndroid Build Coastguard Worker protected: 36*d9f75844SAndroid Build Coastguard Worker // Provided for internal webrtc subclasses for corner cases where it's 37*d9f75844SAndroid Build Coastguard Worker // necessary to know whether or not a reference is exclusively held. HasOneRef()38*d9f75844SAndroid Build Coastguard Worker bool HasOneRef() const { return ref_count_.HasOneRef(); } 39*d9f75844SAndroid Build Coastguard Worker 40*d9f75844SAndroid Build Coastguard Worker virtual ~RefCountedBase() = default; 41*d9f75844SAndroid Build Coastguard Worker 42*d9f75844SAndroid Build Coastguard Worker private: 43*d9f75844SAndroid Build Coastguard Worker mutable webrtc::webrtc_impl::RefCounter ref_count_{0}; 44*d9f75844SAndroid Build Coastguard Worker }; 45*d9f75844SAndroid Build Coastguard Worker 46*d9f75844SAndroid Build Coastguard Worker // Template based version of `RefCountedBase` for simple implementations that do 47*d9f75844SAndroid Build Coastguard Worker // not need (or want) destruction via virtual destructor or the overhead of a 48*d9f75844SAndroid Build Coastguard Worker // vtable. 49*d9f75844SAndroid Build Coastguard Worker // 50*d9f75844SAndroid Build Coastguard Worker // To use: 51*d9f75844SAndroid Build Coastguard Worker // struct MyInt : public rtc::RefCountedNonVirtual<MyInt> { 52*d9f75844SAndroid Build Coastguard Worker // int foo_ = 0; 53*d9f75844SAndroid Build Coastguard Worker // }; 54*d9f75844SAndroid Build Coastguard Worker // 55*d9f75844SAndroid Build Coastguard Worker // rtc::scoped_refptr<MyInt> my_int(new MyInt()); 56*d9f75844SAndroid Build Coastguard Worker // 57*d9f75844SAndroid Build Coastguard Worker // sizeof(MyInt) on a 32 bit system would then be 8, int + refcount and no 58*d9f75844SAndroid Build Coastguard Worker // vtable generated. 59*d9f75844SAndroid Build Coastguard Worker template <typename T> 60*d9f75844SAndroid Build Coastguard Worker class RefCountedNonVirtual { 61*d9f75844SAndroid Build Coastguard Worker public: 62*d9f75844SAndroid Build Coastguard Worker RefCountedNonVirtual() = default; 63*d9f75844SAndroid Build Coastguard Worker 64*d9f75844SAndroid Build Coastguard Worker RefCountedNonVirtual(const RefCountedNonVirtual&) = delete; 65*d9f75844SAndroid Build Coastguard Worker RefCountedNonVirtual& operator=(const RefCountedNonVirtual&) = delete; 66*d9f75844SAndroid Build Coastguard Worker AddRef()67*d9f75844SAndroid Build Coastguard Worker void AddRef() const { ref_count_.IncRef(); } Release()68*d9f75844SAndroid Build Coastguard Worker RefCountReleaseStatus Release() const { 69*d9f75844SAndroid Build Coastguard Worker // If you run into this assert, T has virtual methods. There are two 70*d9f75844SAndroid Build Coastguard Worker // options: 71*d9f75844SAndroid Build Coastguard Worker // 1) The class doesn't actually need virtual methods, the type is complete 72*d9f75844SAndroid Build Coastguard Worker // so the virtual attribute(s) can be removed. 73*d9f75844SAndroid Build Coastguard Worker // 2) The virtual methods are a part of the design of the class. In this 74*d9f75844SAndroid Build Coastguard Worker // case you can consider using `RefCountedBase` instead or alternatively 75*d9f75844SAndroid Build Coastguard Worker // use `rtc::RefCountedObject`. 76*d9f75844SAndroid Build Coastguard Worker static_assert(!std::is_polymorphic<T>::value, 77*d9f75844SAndroid Build Coastguard Worker "T has virtual methods. RefCountedBase is a better fit."); 78*d9f75844SAndroid Build Coastguard Worker const auto status = ref_count_.DecRef(); 79*d9f75844SAndroid Build Coastguard Worker if (status == RefCountReleaseStatus::kDroppedLastRef) { 80*d9f75844SAndroid Build Coastguard Worker delete static_cast<const T*>(this); 81*d9f75844SAndroid Build Coastguard Worker } 82*d9f75844SAndroid Build Coastguard Worker return status; 83*d9f75844SAndroid Build Coastguard Worker } 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker protected: 86*d9f75844SAndroid Build Coastguard Worker // Provided for internal webrtc subclasses for corner cases where it's 87*d9f75844SAndroid Build Coastguard Worker // necessary to know whether or not a reference is exclusively held. HasOneRef()88*d9f75844SAndroid Build Coastguard Worker bool HasOneRef() const { return ref_count_.HasOneRef(); } 89*d9f75844SAndroid Build Coastguard Worker 90*d9f75844SAndroid Build Coastguard Worker ~RefCountedNonVirtual() = default; 91*d9f75844SAndroid Build Coastguard Worker 92*d9f75844SAndroid Build Coastguard Worker private: 93*d9f75844SAndroid Build Coastguard Worker mutable webrtc::webrtc_impl::RefCounter ref_count_{0}; 94*d9f75844SAndroid Build Coastguard Worker }; 95*d9f75844SAndroid Build Coastguard Worker 96*d9f75844SAndroid Build Coastguard Worker } // namespace rtc 97*d9f75844SAndroid Build Coastguard Worker 98*d9f75844SAndroid Build Coastguard Worker #endif // API_REF_COUNTED_BASE_H_ 99