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