Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2020 Project CHIP Authors 4 : * 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : /** 19 : * @file 20 : * This file defines a C++ referenced counted object that auto deletes when 21 : * all references to it have been removed. 22 : */ 23 : 24 : #pragma once 25 : 26 : #include <atomic> 27 : #include <limits> 28 : #include <stdlib.h> 29 : 30 : #include <lib/support/CHIPMem.h> 31 : #include <lib/support/CodeUtils.h> 32 : 33 : namespace chip { 34 : 35 : template <class T> 36 : class DeleteDeletor 37 : { 38 : public: 39 3 : static void Release(T * obj) { chip::Platform::Delete(obj); } 40 : }; 41 : 42 : template <class T> 43 : class NoopDeletor 44 : { 45 : public: 46 0 : static void Release(T * obj) {} 47 : }; 48 : 49 : /** 50 : * A reference counted object maintains a count of usages and when the usage 51 : * count drops to 0, it deletes itself. 52 : */ 53 : template <class Subclass, class Deletor = DeleteDeletor<Subclass>, int kInitRefCount = 1, typename CounterType = uint32_t> 54 : class ReferenceCounted 55 : { 56 : public: 57 : /** Adds one to the usage count of this class */ 58 787640 : Subclass * Retain() 59 : { 60 26996 : VerifyOrDie(!kInitRefCount || mRefCount > 0); 61 787640 : VerifyOrDie(mRefCount < std::numeric_limits<CounterType>::max()); 62 787640 : ++mRefCount; 63 : 64 787640 : return static_cast<Subclass *>(this); 65 : } 66 : 67 : /** Release usage of this class */ 68 790877 : void Release() 69 : { 70 790877 : VerifyOrDie(mRefCount != 0); 71 : 72 790877 : if (--mRefCount == 0) 73 : { 74 138328 : Deletor::Release(static_cast<Subclass *>(this)); 75 : } 76 790877 : } 77 : 78 : /** Get the current reference counter value */ 79 16078 : CounterType GetReferenceCount() const { return mRefCount; } 80 : 81 : private: 82 : CounterType mRefCount = kInitRefCount; 83 : }; 84 : 85 : } // namespace chip