• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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