1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2016 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 RTC_BASE_REF_COUNTED_OBJECT_H_ 11*d9f75844SAndroid Build Coastguard Worker #define RTC_BASE_REF_COUNTED_OBJECT_H_ 12*d9f75844SAndroid Build Coastguard Worker 13*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h" 14*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ref_count.h" 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 template <class T> 20*d9f75844SAndroid Build Coastguard Worker class RefCountedObject : public T { 21*d9f75844SAndroid Build Coastguard Worker public: RefCountedObject()22*d9f75844SAndroid Build Coastguard Worker RefCountedObject() {} 23*d9f75844SAndroid Build Coastguard Worker 24*d9f75844SAndroid Build Coastguard Worker RefCountedObject(const RefCountedObject&) = delete; 25*d9f75844SAndroid Build Coastguard Worker RefCountedObject& operator=(const RefCountedObject&) = delete; 26*d9f75844SAndroid Build Coastguard Worker 27*d9f75844SAndroid Build Coastguard Worker template <class P0> RefCountedObject(P0 && p0)28*d9f75844SAndroid Build Coastguard Worker explicit RefCountedObject(P0&& p0) : T(std::forward<P0>(p0)) {} 29*d9f75844SAndroid Build Coastguard Worker 30*d9f75844SAndroid Build Coastguard Worker template <class P0, class P1, class... Args> RefCountedObject(P0 && p0,P1 && p1,Args &&...args)31*d9f75844SAndroid Build Coastguard Worker RefCountedObject(P0&& p0, P1&& p1, Args&&... args) 32*d9f75844SAndroid Build Coastguard Worker : T(std::forward<P0>(p0), 33*d9f75844SAndroid Build Coastguard Worker std::forward<P1>(p1), 34*d9f75844SAndroid Build Coastguard Worker std::forward<Args>(args)...) {} 35*d9f75844SAndroid Build Coastguard Worker AddRef()36*d9f75844SAndroid Build Coastguard Worker void AddRef() const override { ref_count_.IncRef(); } 37*d9f75844SAndroid Build Coastguard Worker Release()38*d9f75844SAndroid Build Coastguard Worker RefCountReleaseStatus Release() const override { 39*d9f75844SAndroid Build Coastguard Worker const auto status = ref_count_.DecRef(); 40*d9f75844SAndroid Build Coastguard Worker if (status == RefCountReleaseStatus::kDroppedLastRef) { 41*d9f75844SAndroid Build Coastguard Worker delete this; 42*d9f75844SAndroid Build Coastguard Worker } 43*d9f75844SAndroid Build Coastguard Worker return status; 44*d9f75844SAndroid Build Coastguard Worker } 45*d9f75844SAndroid Build Coastguard Worker 46*d9f75844SAndroid Build Coastguard Worker // Return whether the reference count is one. If the reference count is used 47*d9f75844SAndroid Build Coastguard Worker // in the conventional way, a reference count of 1 implies that the current 48*d9f75844SAndroid Build Coastguard Worker // thread owns the reference and no other thread shares it. This call 49*d9f75844SAndroid Build Coastguard Worker // performs the test for a reference count of one, and performs the memory 50*d9f75844SAndroid Build Coastguard Worker // barrier needed for the owning thread to act on the object, knowing that it 51*d9f75844SAndroid Build Coastguard Worker // has exclusive access to the object. HasOneRef()52*d9f75844SAndroid Build Coastguard Worker virtual bool HasOneRef() const { return ref_count_.HasOneRef(); } 53*d9f75844SAndroid Build Coastguard Worker 54*d9f75844SAndroid Build Coastguard Worker protected: ~RefCountedObject()55*d9f75844SAndroid Build Coastguard Worker ~RefCountedObject() override {} 56*d9f75844SAndroid Build Coastguard Worker 57*d9f75844SAndroid Build Coastguard Worker mutable webrtc::webrtc_impl::RefCounter ref_count_{0}; 58*d9f75844SAndroid Build Coastguard Worker }; 59*d9f75844SAndroid Build Coastguard Worker 60*d9f75844SAndroid Build Coastguard Worker template <class T> 61*d9f75844SAndroid Build Coastguard Worker class FinalRefCountedObject final : public T { 62*d9f75844SAndroid Build Coastguard Worker public: 63*d9f75844SAndroid Build Coastguard Worker using T::T; 64*d9f75844SAndroid Build Coastguard Worker // Above using declaration propagates a default move constructor 65*d9f75844SAndroid Build Coastguard Worker // FinalRefCountedObject(FinalRefCountedObject&& other), but we also need 66*d9f75844SAndroid Build Coastguard Worker // move construction from T. FinalRefCountedObject(T && other)67*d9f75844SAndroid Build Coastguard Worker explicit FinalRefCountedObject(T&& other) : T(std::move(other)) {} 68*d9f75844SAndroid Build Coastguard Worker FinalRefCountedObject(const FinalRefCountedObject&) = delete; 69*d9f75844SAndroid Build Coastguard Worker FinalRefCountedObject& operator=(const FinalRefCountedObject&) = delete; 70*d9f75844SAndroid Build Coastguard Worker AddRef()71*d9f75844SAndroid Build Coastguard Worker void AddRef() const { ref_count_.IncRef(); } Release()72*d9f75844SAndroid Build Coastguard Worker RefCountReleaseStatus Release() const { 73*d9f75844SAndroid Build Coastguard Worker const auto status = ref_count_.DecRef(); 74*d9f75844SAndroid Build Coastguard Worker if (status == RefCountReleaseStatus::kDroppedLastRef) { 75*d9f75844SAndroid Build Coastguard Worker delete this; 76*d9f75844SAndroid Build Coastguard Worker } 77*d9f75844SAndroid Build Coastguard Worker return status; 78*d9f75844SAndroid Build Coastguard Worker } HasOneRef()79*d9f75844SAndroid Build Coastguard Worker bool HasOneRef() const { return ref_count_.HasOneRef(); } 80*d9f75844SAndroid Build Coastguard Worker 81*d9f75844SAndroid Build Coastguard Worker private: 82*d9f75844SAndroid Build Coastguard Worker ~FinalRefCountedObject() = default; 83*d9f75844SAndroid Build Coastguard Worker 84*d9f75844SAndroid Build Coastguard Worker mutable webrtc::webrtc_impl::RefCounter ref_count_{0}; 85*d9f75844SAndroid Build Coastguard Worker }; 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker } // namespace rtc 88*d9f75844SAndroid Build Coastguard Worker 89*d9f75844SAndroid Build Coastguard Worker #endif // RTC_BASE_REF_COUNTED_OBJECT_H_ 90