1 /* 2 * Copyright (C) 2017 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 #pragma once 18 19 /* 20 * See documentation in RefBase.h 21 */ 22 23 #include <atomic> 24 25 #include <sys/types.h> 26 27 namespace android { 28 29 class ReferenceRenamer; 30 31 void LightRefBase_reportIncStrongRequireStrongFailed(const void* thiz); 32 33 template <class T> 34 class LightRefBase 35 { 36 public: LightRefBase()37 inline LightRefBase() : mCount(0) { } incStrong(const void * id)38 inline void incStrong(__attribute__((unused)) const void* id) const { 39 mCount.fetch_add(1, std::memory_order_relaxed); 40 } incStrongRequireStrong(const void * id)41 inline void incStrongRequireStrong(__attribute__((unused)) const void* id) const { 42 if (0 == mCount.fetch_add(1, std::memory_order_relaxed)) { 43 LightRefBase_reportIncStrongRequireStrongFailed(this); 44 } 45 } decStrong(const void * id)46 inline void decStrong(__attribute__((unused)) const void* id) const { 47 if (mCount.fetch_sub(1, std::memory_order_release) == 1) { 48 std::atomic_thread_fence(std::memory_order_acquire); 49 delete static_cast<const T*>(this); 50 } 51 } 52 //! DEBUGGING ONLY: Get current strong ref count. getStrongCount()53 inline int32_t getStrongCount() const { 54 return mCount.load(std::memory_order_relaxed); 55 } 56 57 protected: ~LightRefBase()58 inline ~LightRefBase() { } 59 60 private: 61 friend class ReferenceMover; renameRefs(size_t,const ReferenceRenamer &)62 inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } renameRefId(T *,const void *,const void *)63 inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { } 64 65 private: 66 mutable std::atomic<int32_t> mCount; 67 }; 68 69 // This is a wrapper around LightRefBase that simply enforces a virtual 70 // destructor to eliminate the template requirement of LightRefBase 71 class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { 72 public: 73 virtual ~VirtualLightRefBase() = default; 74 }; 75 76 } // namespace android 77