1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHRE_UTIL_SYSTEM_REF_BASE_H_
18 #define CHRE_UTIL_SYSTEM_REF_BASE_H_
19 
20 #include <cstdint>
21 
22 #include "chre/platform/assert.h"
23 #include "chre/platform/atomic.h"
24 #include "chre/platform/memory.h"
25 
26 namespace chre {
27 
28 /**
29  * Base class for any type that needs to support reference counting.
30  */
31 template <class T>
32 class RefBase {
33  public:
34   /**
35    * Increments the reference count for this object.
36    */
incRef()37   void incRef() const {
38     mRefCount.fetch_increment();
39   }
40 
41   /**
42    * Decrements the reference count for this object. If this invocation takes
43    * the reference count to zero, the object will be destroyed and its memory
44    * will be released.
45    */
decRef()46   void decRef() const {
47     uint32_t refCount = mRefCount.fetch_decrement();
48     CHRE_ASSERT(refCount > 0);
49     if (refCount == 1) {
50       T *obj = const_cast<T *>(static_cast<const T *>(this));
51       obj->~T();
52       memoryFree(obj);
53     }
54   }
55 
56  protected:
57   /**
58    * Destructor is protected so this object cannot be directly destroyed.
59    */
~RefBase()60   virtual ~RefBase() {}
61 
62  private:
63   // Ref count should always start at 1 since something must reference this
64   // object to have created it.
65   mutable AtomicUint32 mRefCount{1};
66 };
67 
68 }  // namespace chre
69 
70 #endif  // CHRE_UTIL_SYSTEM_REF_BASE_H_
71