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 792063 : Subclass * Retain()
59 : {
60 27727 : VerifyOrDie(!kInitRefCount || mRefCount > 0);
61 792063 : VerifyOrDie(mRefCount < std::numeric_limits<CounterType>::max());
62 792063 : ++mRefCount;
63 :
64 792063 : return static_cast<Subclass *>(this);
65 : }
66 :
67 : /** Release usage of this class */
68 795471 : void Release()
69 : {
70 795471 : VerifyOrDie(mRefCount != 0);
71 :
72 795471 : if (--mRefCount == 0)
73 : {
74 138642 : Deletor::Release(static_cast<Subclass *>(this));
75 : }
76 795471 : }
77 :
78 : /** Get the current reference counter value */
79 16638 : CounterType GetReferenceCount() const { return mRefCount; }
80 :
81 : private:
82 : CounterType mRefCount = kInitRefCount;
83 : };
84 :
85 : } // namespace chip
|