diff options
| -rw-r--r-- | libutils/RefBase.cpp | 2 | ||||
| -rw-r--r-- | libutils/include/utils/LightRefBase.h | 72 | ||||
| -rw-r--r-- | libutils/include/utils/RefBase.h | 75 |
3 files changed, 90 insertions, 59 deletions
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp index 0d98db949..24737b985 100644 --- a/libutils/RefBase.cpp +++ b/libutils/RefBase.cpp @@ -760,6 +760,4 @@ void RefBase::renameRefId(RefBase* ref, ref->mRefs->renameWeakRefId(old_id, new_id); } -VirtualLightRefBase::~VirtualLightRefBase() {} - }; // namespace android diff --git a/libutils/include/utils/LightRefBase.h b/libutils/include/utils/LightRefBase.h new file mode 100644 index 000000000..65257edb9 --- /dev/null +++ b/libutils/include/utils/LightRefBase.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +/* + * See documentation in RefBase.h + */ + +#include <atomic> + +#include <sys/types.h> + +namespace android { + +class ReferenceRenamer; + +template <class T> +class LightRefBase +{ +public: + inline LightRefBase() : mCount(0) { } + inline void incStrong(__attribute__((unused)) const void* id) const { + mCount.fetch_add(1, std::memory_order_relaxed); + } + inline void decStrong(__attribute__((unused)) const void* id) const { + if (mCount.fetch_sub(1, std::memory_order_release) == 1) { + std::atomic_thread_fence(std::memory_order_acquire); + delete static_cast<const T*>(this); + } + } + //! DEBUGGING ONLY: Get current strong ref count. + inline int32_t getStrongCount() const { + return mCount.load(std::memory_order_relaxed); + } + + typedef LightRefBase<T> basetype; + +protected: + inline ~LightRefBase() { } + +private: + friend class ReferenceMover; + inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } + inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { } + +private: + mutable std::atomic<int32_t> mCount; +}; + + +// This is a wrapper around LightRefBase that simply enforces a virtual +// destructor to eliminate the template requirement of LightRefBase +class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { +public: + virtual ~VirtualLightRefBase() = default; +}; + +}; // namespace android diff --git a/libutils/include/utils/RefBase.h b/libutils/include/utils/RefBase.h index a61ea58f4..223b6669d 100644 --- a/libutils/include/utils/RefBase.h +++ b/libutils/include/utils/RefBase.h @@ -177,6 +177,9 @@ #include <stdlib.h> #include <string.h> +// LightRefBase used to be declared in this header, so we have to include it +#include <utils/LightRefBase.h> + #include <utils/StrongPointer.h> #include <utils/TypeHelpers.h> @@ -216,7 +219,7 @@ inline bool operator _op_ (const U* o) const { \ class ReferenceRenamer { protected: - // destructor is purposedly not virtual so we avoid code overhead from + // destructor is purposely not virtual so we avoid code overhead from // subclasses; we have to make it protected to guarantee that it // cannot be called from this base class (and to make strict compilers // happy). @@ -246,13 +249,13 @@ public: { public: RefBase* refBase() const; - + void incWeak(const void* id); void decWeak(const void* id); - + // acquires a strong reference if there is already one. bool attemptIncStrong(const void* id); - + // acquires a weak reference if there is already one. // This is not always safe. see ProcessState.cpp and BpBinder.cpp // for proper use. @@ -268,12 +271,12 @@ public: // enable -- enable/disable tracking // retain -- when tracking is enable, if true, then we save a stack trace // for each reference and dereference; when retain == false, we - // match up references and dereferences and keep only the + // match up references and dereferences and keep only the // outstanding ones. - + void trackMe(bool enable, bool retain); }; - + weakref_type* createWeak(const void* id) const; weakref_type* getWeakRefs() const; @@ -345,54 +348,12 @@ private: // --------------------------------------------------------------------------- -template <class T> -class LightRefBase -{ -public: - inline LightRefBase() : mCount(0) { } - inline void incStrong(__attribute__((unused)) const void* id) const { - mCount.fetch_add(1, std::memory_order_relaxed); - } - inline void decStrong(__attribute__((unused)) const void* id) const { - if (mCount.fetch_sub(1, std::memory_order_release) == 1) { - std::atomic_thread_fence(std::memory_order_acquire); - delete static_cast<const T*>(this); - } - } - //! DEBUGGING ONLY: Get current strong ref count. - inline int32_t getStrongCount() const { - return mCount.load(std::memory_order_relaxed); - } - - typedef LightRefBase<T> basetype; - -protected: - inline ~LightRefBase() { } - -private: - friend class ReferenceMover; - inline static void renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } - inline static void renameRefId(T* /*ref*/, const void* /*old_id*/ , const void* /*new_id*/) { } - -private: - mutable std::atomic<int32_t> mCount; -}; - -// This is a wrapper around LightRefBase that simply enforces a virtual -// destructor to eliminate the template requirement of LightRefBase -class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { -public: - virtual ~VirtualLightRefBase(); -}; - -// --------------------------------------------------------------------------- - template <typename T> class wp { public: typedef typename RefBase::weakref_type weakref_type; - + inline wp() : m_ptr(0) { } wp(T* other); // NOLINT(implicit) @@ -403,31 +364,31 @@ public: template<typename U> wp(const wp<U>& other); // NOLINT(implicit) ~wp(); - + // Assignment wp& operator = (T* other); wp& operator = (const wp<T>& other); wp& operator = (const sp<T>& other); - + template<typename U> wp& operator = (U* other); template<typename U> wp& operator = (const wp<U>& other); template<typename U> wp& operator = (const sp<U>& other); - + void set_object_and_refs(T* other, weakref_type* refs); // promotion to sp - + sp<T> promote() const; // Reset - + void clear(); // Accessors - + inline weakref_type* get_refs() const { return m_refs; } - + inline T* unsafe_get() const { return m_ptr; } // Operators |
