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_SHARED_PTR_H_ 18 #define CHRE_UTIL_SYSTEM_SHARED_PTR_H_ 19 20 #include <cstddef> 21 22 namespace chre { 23 24 /** 25 * Wraps a pointer to a dynamically allocated object and manages the underlying 26 * memory. The goal is to be similar to std::shared_ptr, but we do not support 27 * custom deleters - deletion is always done via memoryFree(). 28 * 29 * NOTE: Be very careful to avoid circular SharedPtr references since this can 30 * cause leaks that are hard to debug. For a full list of caveats and tips, 31 * check out system/core/libutils/include/utils/RefBase.h. 32 */ 33 template <typename ObjectType> 34 class SharedPtr { 35 public: 36 /** 37 * Pointer type of ObjectType. 38 */ 39 typedef ObjectType *pointer; 40 41 /** 42 * Construct a SharedPtr instance that does not own any object. 43 */ 44 SharedPtr(); 45 46 /** 47 * Constructs a SharedPtr instance that owns the given object, and will free 48 * its memory when all SharedPtr references have been destroyed. 49 * 50 * @param object Pointer to an object allocated via memoryAlloc. It is not 51 * valid for this object's memory to come from any other source, 52 * including the stack, or static allocation on the heap. 53 */ 54 SharedPtr(ObjectType *object); 55 56 /** 57 * Constructs a new SharedPtr via moving the Object reference from another 58 * SharedPtr. 59 * 60 * @param other SharedPtr instance to move into this object 61 */ 62 SharedPtr(SharedPtr<ObjectType> &&other); 63 64 /** 65 * Constructs a new SharedPtr via moving the Object reference from another 66 * SharedPtr. This constructor allows conversion (ie: upcast) to another type 67 * if possible. 68 * 69 * @param other SharedPtr instance to move and convert into this object. 70 */ 71 template <typename OtherObjectType> 72 SharedPtr(SharedPtr<OtherObjectType> &&other); 73 74 /** 75 * Constructs a new SharedPtr by creating a new reference to 'other' so each 76 * SharedPtr will have its own reference. 77 * 78 * @param other SharedPtr instance containing data to be referenced by this 79 * pointer. 80 */ 81 SharedPtr(const SharedPtr &other); 82 83 /** 84 * Constructs a new SharedPtr via creating a new reference to the Object so 85 * each SharedPtr will have its own ref. This constructor allows conversion 86 * (ie: upcast) to another type if possible. 87 * 88 * @param other SharedPtr instance containing data to be referenced by this 89 * pointer. 90 */ 91 template <typename OtherObjectType> 92 SharedPtr(const SharedPtr<OtherObjectType> &other); 93 94 /** 95 * Deconstructs the object (if necessary) and releases associated memory if 96 * no other references to the memory exist. 97 */ 98 ~SharedPtr(); 99 100 /** 101 * Determines if this SharedPtr owns an object, or references null. 102 * 103 * @return true if get() returns nullptr 104 */ 105 bool isNull() const; 106 107 /** 108 * @return A pointer to the underlying object, or nullptr if this object is 109 * not currently valid. 110 */ 111 ObjectType *get() const; 112 113 /** 114 * Replaces the object referenced by the SharedPtr by an object pointed by a 115 * given pointer. Also calls the dereferences the associated memory of the 116 * previously referenced object. Invoking this method on the object managed by 117 * the SharedPtr, obtained via get(), is illegal. 118 * 119 * @param object the object to be referenced by the SharedPtr 120 */ 121 void reset(ObjectType *object); 122 123 /** 124 * Dereferences the object owned by the SharedPtr. If necessary, calls the 125 * destructor and releases the associated memory of the previously referenced 126 * object. 127 */ 128 void reset(); 129 130 /** 131 * @return A pointer to the underlying object. 132 */ 133 ObjectType *operator->() const; 134 135 /** 136 * @return A reference to the underlying object. 137 */ 138 ObjectType &operator*() const; 139 140 /** 141 * @param index The index of an object in the underlying array object. 142 * @return A reference to the underlying object at an index. 143 */ 144 ObjectType &operator[](size_t index) const; 145 146 /** 147 * Copy assignment operator. The new SharedPtr object has a new reference to 148 * the underlying object and the existing SharedPtr object retains its 149 * reference. 150 * 151 * @param other The other object being copied. 152 * @return A reference to the newly copied object. 153 */ 154 SharedPtr<ObjectType> &operator=(const SharedPtr<ObjectType> &other); 155 156 /** 157 * Move assignment operator. Ownership of this object is transferred and the 158 * other object is left in an invalid state. 159 * 160 * @param other The other object being moved. 161 * @return A reference to the newly moved object. 162 */ 163 SharedPtr<ObjectType> &operator=(SharedPtr<ObjectType> &&other); 164 165 /** 166 * Two SharedPtr compare equal (==) if their stored pointers compare equal, 167 * and not equal (!=) otherwise. 168 * 169 * @param other The other object being compared. 170 * @return true if the other's pointer is same as the underlying pointer, 171 * otherwise false. 172 */ 173 bool operator==(const SharedPtr<ObjectType> &other) const; 174 175 /** 176 * Two SharedPtr compare equal (==) if their stored pointers compare equal, 177 * and not equal (!=) otherwise. 178 * 179 * @param other The other object being compared. 180 * @return true if the other's pointer is different than the underlying 181 * pointer, otherwise false. 182 */ 183 bool operator!=(const SharedPtr<ObjectType> &other) const; 184 185 private: 186 // Befriend this class to itself to allow the templated conversion constructor 187 // permission to access mObject below. 188 template <typename OtherObjectType> 189 friend class SharedPtr; 190 191 //! A pointer to the underlying storage for this object. 192 ObjectType *mObject = nullptr; 193 }; 194 195 /** 196 * Allocates and constructs a new object of type ObjectType on the heap, and 197 * returns a SharedPtr that references the object. This function is similar to 198 * std::make_shared. 199 * 200 * @param args The arguments to pass to the object's constructor. 201 */ 202 template <typename ObjectType, typename... Args> 203 SharedPtr<ObjectType> MakeShared(Args &&...args); 204 205 /** 206 * Just like MakeShared(), except it zeros out any allocated memory. Intended to 207 * be used for creating objects that have trivial constructors (e.g. C structs) 208 * but should start with a known state. 209 */ 210 template <typename ObjectType> 211 SharedPtr<ObjectType> MakeSharedZeroFill(); 212 213 } // namespace chre 214 215 #include "chre/util/system/shared_ptr_impl.h" 216 217 #endif // CHRE_UTIL_SYSTEM_SHARED_PTR_H_ 218