1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef META_BASE_SHARED_PTR_INTERNALS_H 17 #define META_BASE_SHARED_PTR_INTERNALS_H 18 19 #include <base/containers/unique_ptr.h> 20 #include <base/namespace.h> 21 #include <core/log.h> 22 23 #include <meta/base/atomics.h> 24 #include <meta/base/interface_macros.h> 25 #include <meta/base/interface_traits.h> 26 27 BASE_BEGIN_NAMESPACE() 28 namespace Internals { 29 30 template<typename U, typename T> 31 using EnableIfPointerConvertible = BASE_NS::enable_if_t<BASE_NS::is_convertible_v<U*, T*>>; 32 33 class ControlBlock { 34 public: 35 ControlBlock() = default; 36 virtual ~ControlBlock() = default; 37 META_NO_COPY_MOVE(ControlBlock) 38 AddStrongCopy()39 void AddStrongCopy() 40 { 41 CORE_NS::AtomicIncrement(&strongCount_); 42 } 43 AddWeak()44 void AddWeak() 45 { 46 CORE_NS::AtomicIncrement(&weakCount_); 47 } 48 Release()49 void Release() 50 { 51 if (CORE_NS::AtomicDecrement(&strongCount_) == 0) { 52 Dispose(); 53 // The strong references are counted as one weak references to keep the control block alive 54 ReleaseWeak(); 55 } 56 } 57 ReleaseWeak()58 void ReleaseWeak() 59 { 60 // The weak count is initialised to 1, so releasing weak pointers does not destroy 61 // the control block unless there is no more strong references 62 if (CORE_NS::AtomicDecrement(&weakCount_) == 0) { 63 Destroy(); 64 } 65 } 66 AddStrongLock()67 bool AddStrongLock() 68 { 69 return CORE_NS::AtomicIncrementIfNotZero(&strongCount_) != 0; 70 } 71 GetStrongCount() const72 int32_t GetStrongCount() const 73 { 74 return CORE_NS::AtomicRead(&strongCount_); 75 } 76 77 virtual void Destroy() = 0; 78 virtual void Dispose() = 0; 79 80 private: 81 // Count of the weak references +1 for the strong references 82 int32_t weakCount_ { 1 }; 83 int32_t strongCount_ { 1 }; 84 }; 85 86 class ptr_base { 87 protected: 88 ptr_base() = default; 89 ~ptr_base() = default; 90 ptr_base(const ptr_base&) = default; 91 ptr_base(ptr_base&&) = default; 92 ptr_base& operator=(const ptr_base&) = default; 93 ptr_base& operator=(ptr_base&&) = default; 94 }; 95 96 template<typename Type> 97 class PtrCountedBase : public ptr_base { 98 public: 99 // for compatibility 100 template<typename U> Compare(const PtrCountedBase<U>& p) const101 bool Compare(const PtrCountedBase<U>& p) const 102 { 103 return static_cast<const void*>(pointer_) == static_cast<const void*>(p.pointer_); 104 } 105 template<typename U> CompareOwner(const PtrCountedBase<U>& p) const106 bool CompareOwner(const PtrCountedBase<U>& p) const 107 { 108 return control_ == p.control_; 109 } 110 111 protected: 112 PtrCountedBase() = default; PtrCountedBase(ControlBlock* c)113 PtrCountedBase(ControlBlock* c) : control_(c) {} 114 ~PtrCountedBase() = default; 115 PtrCountedBase(const PtrCountedBase&) = default; 116 PtrCountedBase& operator=(const PtrCountedBase&) = default; 117 PtrCountedBase(PtrCountedBase&&) = default; 118 PtrCountedBase& operator=(PtrCountedBase&&) = default; 119 InternalReset()120 void InternalReset() 121 { 122 control_ = nullptr; 123 pointer_ = nullptr; 124 } 125 126 protected: 127 Type* pointer_ {}; 128 ControlBlock* control_ {}; 129 130 template<typename> 131 friend class PtrCountedBase; 132 }; 133 134 template<typename T> 135 using DefaultDeleterType = void (*)(T*); 136 137 template<typename T> 138 class StorageBlock final : public ControlBlock { 139 public: StorageBlock(T* ptr)140 explicit StorageBlock(T* ptr) : ptr_ { ptr } 141 { 142 } 143 144 void Destroy() final 145 { 146 delete this; 147 } 148 149 void Dispose() final 150 { 151 delete ptr_; 152 } 153 154 private: 155 T* ptr_ { nullptr }; 156 }; 157 158 template<typename T, typename Deleter = DefaultDeleterType<T>> 159 class StorageBlockWithDeleter final : public ControlBlock { 160 public: StorageBlockWithDeleter(T* ptr, Deleter deleter)161 StorageBlockWithDeleter(T* ptr, Deleter deleter) : ptr_ { ptr }, deleter_ { BASE_NS::move(deleter) } 162 { 163 } 164 165 void Destroy() final 166 { 167 delete this; 168 } 169 170 void Dispose() final 171 { 172 deleter_(ptr_); 173 } 174 175 private: 176 T* ptr_ { nullptr }; 177 Deleter deleter_; 178 }; 179 180 template<typename T> 181 class RefCountedObjectStorageBlock final : public ControlBlock { 182 public: 183 using deletableType = BASE_NS::remove_const_t<T>; 184 RefCountedObjectStorageBlock(T* ptr)185 explicit RefCountedObjectStorageBlock(T* ptr) : ptr_ { ptr } 186 { 187 const_cast<deletableType*>(ptr)->Ref(); 188 } 189 190 void Destroy() final 191 { 192 delete this; 193 } 194 195 void Dispose() final 196 { 197 const_cast<deletableType*>(ptr_)->Unref(); 198 } 199 200 private: 201 T* ptr_ { nullptr }; 202 }; 203 204 } // namespace Internals 205 BASE_END_NAMESPACE() 206 207 #endif 208