diff options
author | Mathias Agopian <mathias@google.com> | 2011-02-24 16:23:51 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-02-24 16:23:51 -0800 |
commit | ffbe826804e150013acbf3ab25bd405bbbd186fc (patch) | |
tree | 51fae9c95265246e6de2100556cb7d68746f9614 /include/utils | |
parent | a28f6f11f22963e3679537e83f243edeaa5ee17c (diff) | |
parent | ec122eb46b6ce8f6e8bb3e08c34e575de666cd3e (diff) | |
download | frameworks_base-ffbe826804e150013acbf3ab25bd405bbbd186fc.zip frameworks_base-ffbe826804e150013acbf3ab25bd405bbbd186fc.tar.gz frameworks_base-ffbe826804e150013acbf3ab25bd405bbbd186fc.tar.bz2 |
Merge "Fix some issues with RefBase debugging."
Diffstat (limited to 'include/utils')
-rw-r--r-- | include/utils/RefBase.h | 277 | ||||
-rw-r--r-- | include/utils/StrongPointer.h | 224 | ||||
-rw-r--r-- | include/utils/TypeHelpers.h | 13 |
3 files changed, 325 insertions, 189 deletions
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h index f8d96cf..9b0e7d8 100644 --- a/include/utils/RefBase.h +++ b/include/utils/RefBase.h @@ -22,16 +22,16 @@ #include <stdint.h> #include <sys/types.h> #include <stdlib.h> +#include <string.h> + +#include <utils/StrongPointer.h> // --------------------------------------------------------------------------- namespace android { class TextOutput; -TextOutput& printStrongPointer(TextOutput& to, const void* val); TextOutput& printWeakPointer(TextOutput& to, const void* val); -template<typename T> class wp; - // --------------------------------------------------------------------------- #define COMPARE_WEAK(_op_) \ @@ -50,15 +50,15 @@ inline bool operator _op_ (const U* o) const { \ return m_ptr _op_ o; \ } -#define COMPARE(_op_) \ -COMPARE_WEAK(_op_) \ -inline bool operator _op_ (const wp<T>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -template<typename U> \ -inline bool operator _op_ (const wp<U>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} +// --------------------------------------------------------------------------- + +class ReferenceMover; +class ReferenceConverterBase { +public: + virtual size_t getReferenceTypeSize() const = 0; + virtual void* getReferenceBase(void const*) const = 0; + inline virtual ~ReferenceConverterBase() { } +}; // --------------------------------------------------------------------------- @@ -115,6 +115,8 @@ public: getWeakRefs()->trackMe(enable, retain); } + typedef RefBase basetype; + protected: RefBase(); virtual ~RefBase(); @@ -138,6 +140,11 @@ protected: virtual void onLastWeakRef(const void* id); private: + friend class ReferenceMover; + static void moveReferences(void* d, void const* s, size_t n, + const ReferenceConverterBase& caster); + +private: friend class weakref_type; class weakref_impl; @@ -166,74 +173,21 @@ public: inline int32_t getStrongCount() const { return mCount; } - -protected: - inline ~LightRefBase() { } - -private: - mutable volatile int32_t mCount; -}; - -// --------------------------------------------------------------------------- - -template <typename T> -class sp -{ -public: - typedef typename RefBase::weakref_type weakref_type; - - inline sp() : m_ptr(0) { } - - sp(T* other); - sp(const sp<T>& other); - template<typename U> sp(U* other); - template<typename U> sp(const sp<U>& other); - - ~sp(); - - // Assignment - sp& operator = (T* other); - sp& operator = (const sp<T>& other); - - template<typename U> sp& operator = (const sp<U>& other); - template<typename U> sp& operator = (U* other); - - //! Special optimization for use by ProcessState (and nobody else). - void force_set(T* other); - - // Reset - - void clear(); - - // Accessors + typedef LightRefBase<T> basetype; - inline T& operator* () const { return *m_ptr; } - inline T* operator-> () const { return m_ptr; } - inline T* get() const { return m_ptr; } +protected: + inline ~LightRefBase() { } - // Operators - - COMPARE(==) - COMPARE(!=) - COMPARE(>) - COMPARE(<) - COMPARE(<=) - COMPARE(>=) - -private: - template<typename Y> friend class sp; - template<typename Y> friend class wp; +private: + friend class ReferenceMover; + inline static void moveReferences(void* d, void const* s, size_t n, + const ReferenceConverterBase& caster) { } - // Optimization for wp::promote(). - sp(T* p, weakref_type* refs); - - T* m_ptr; +private: + mutable volatile int32_t mCount; }; -template <typename T> -TextOutput& operator<<(TextOutput& to, const sp<T>& val); - // --------------------------------------------------------------------------- template <typename T> @@ -329,113 +283,12 @@ private: template <typename T> TextOutput& operator<<(TextOutput& to, const wp<T>& val); -#undef COMPARE #undef COMPARE_WEAK // --------------------------------------------------------------------------- // No user serviceable parts below here. template<typename T> -sp<T>::sp(T* other) - : m_ptr(other) -{ - if (other) other->incStrong(this); -} - -template<typename T> -sp<T>::sp(const sp<T>& other) - : m_ptr(other.m_ptr) -{ - if (m_ptr) m_ptr->incStrong(this); -} - -template<typename T> template<typename U> -sp<T>::sp(U* other) : m_ptr(other) -{ - if (other) other->incStrong(this); -} - -template<typename T> template<typename U> -sp<T>::sp(const sp<U>& other) - : m_ptr(other.m_ptr) -{ - if (m_ptr) m_ptr->incStrong(this); -} - -template<typename T> -sp<T>::~sp() -{ - if (m_ptr) m_ptr->decStrong(this); -} - -template<typename T> -sp<T>& sp<T>::operator = (const sp<T>& other) { - T* otherPtr(other.m_ptr); - if (otherPtr) otherPtr->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = otherPtr; - return *this; -} - -template<typename T> -sp<T>& sp<T>::operator = (T* other) -{ - if (other) other->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = other; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator = (const sp<U>& other) -{ - U* otherPtr(other.m_ptr); - if (otherPtr) otherPtr->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = otherPtr; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator = (U* other) -{ - if (other) other->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = other; - return *this; -} - -template<typename T> -void sp<T>::force_set(T* other) -{ - other->forceIncStrong(this); - m_ptr = other; -} - -template<typename T> -void sp<T>::clear() -{ - if (m_ptr) { - m_ptr->decStrong(this); - m_ptr = 0; - } -} - -template<typename T> -sp<T>::sp(T* p, weakref_type* refs) - : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0) -{ -} - -template <typename T> -inline TextOutput& operator<<(TextOutput& to, const sp<T>& val) -{ - return printStrongPointer(to, val.get()); -} - -// --------------------------------------------------------------------------- - -template<typename T> wp<T>::wp(T* other) : m_ptr(other) { @@ -572,7 +425,8 @@ void wp<T>::set_object_and_refs(T* other, weakref_type* refs) template<typename T> sp<T> wp<T>::promote() const { - return sp<T>(m_ptr, m_refs); + T* p = (m_ptr && m_refs->attemptIncStrong(this)) ? m_ptr : 0; + return sp<T>(p, true); } template<typename T> @@ -590,6 +444,77 @@ inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) return printWeakPointer(to, val.unsafe_get()); } +// --------------------------------------------------------------------------- + +// this class just serves as a namespace so TYPE::moveReferences can stay +// private. + +class ReferenceMover { + // StrongReferenceCast and WeakReferenceCast do the impedance matching + // between the generic (void*) implementation in Refbase and the strongly typed + // template specializations below. + + template <typename TYPE> + struct StrongReferenceCast : public ReferenceConverterBase { + virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); } + virtual void* getReferenceBase(void const* p) const { + sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p)); + return static_cast<typename TYPE::basetype *>(sptr->get()); + } + }; + + template <typename TYPE> + struct WeakReferenceCast : public ReferenceConverterBase { + virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); } + virtual void* getReferenceBase(void const* p) const { + wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p)); + return static_cast<typename TYPE::basetype *>(sptr->unsafe_get()); + } + }; + +public: + template<typename TYPE> static inline + void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { + memmove(d, s, n*sizeof(sp<TYPE>)); + StrongReferenceCast<TYPE> caster; + TYPE::moveReferences(d, s, n, caster); + } + template<typename TYPE> static inline + void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { + memmove(d, s, n*sizeof(wp<TYPE>)); + WeakReferenceCast<TYPE> caster; + TYPE::moveReferences(d, s, n, caster); + } +}; + +// specialization for moving sp<> and wp<> types. +// these are used by the [Sorted|Keyed]Vector<> implementations +// sp<> and wp<> need to be handled specially, because they do not +// have trivial copy operation in the general case (see RefBase.cpp +// when DEBUG ops are enabled), but can be implemented very +// efficiently in most cases. + +template<typename TYPE> inline +void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + +template<typename TYPE> inline +void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + +template<typename TYPE> inline +void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + +template<typename TYPE> inline +void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { + ReferenceMover::move_references(d, s, n); +} + + }; // namespace android // --------------------------------------------------------------------------- diff --git a/include/utils/StrongPointer.h b/include/utils/StrongPointer.h new file mode 100644 index 0000000..5daccf4 --- /dev/null +++ b/include/utils/StrongPointer.h @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2005 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. + */ + +#ifndef ANDROID_STRONG_POINTER_H +#define ANDROID_STRONG_POINTER_H + +#include <cutils/atomic.h> + +#include <stdint.h> +#include <sys/types.h> +#include <stdlib.h> + +// --------------------------------------------------------------------------- +namespace android { + +class TextOutput; +TextOutput& printStrongPointer(TextOutput& to, const void* val); + +template<typename T> class wp; + +// --------------------------------------------------------------------------- + +#define COMPARE(_op_) \ +inline bool operator _op_ (const sp<T>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +inline bool operator _op_ (const T* o) const { \ + return m_ptr _op_ o; \ +} \ +template<typename U> \ +inline bool operator _op_ (const sp<U>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +template<typename U> \ +inline bool operator _op_ (const U* o) const { \ + return m_ptr _op_ o; \ +} \ +inline bool operator _op_ (const wp<T>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} \ +template<typename U> \ +inline bool operator _op_ (const wp<U>& o) const { \ + return m_ptr _op_ o.m_ptr; \ +} + +// --------------------------------------------------------------------------- + +template <typename T> +class sp +{ +public: + inline sp() : m_ptr(0) { } + + sp(T* other); + sp(const sp<T>& other); + template<typename U> sp(U* other); + template<typename U> sp(const sp<U>& other); + + ~sp(); + + // Assignment + + sp& operator = (T* other); + sp& operator = (const sp<T>& other); + + template<typename U> sp& operator = (const sp<U>& other); + template<typename U> sp& operator = (U* other); + + //! Special optimization for use by ProcessState (and nobody else). + void force_set(T* other); + + // Reset + + void clear(); + + // Accessors + + inline T& operator* () const { return *m_ptr; } + inline T* operator-> () const { return m_ptr; } + inline T* get() const { return m_ptr; } + + // Operators + + COMPARE(==) + COMPARE(!=) + COMPARE(>) + COMPARE(<) + COMPARE(<=) + COMPARE(>=) + +private: + template<typename Y> friend class sp; + template<typename Y> friend class wp; + + // Optimization for wp::promote(). + sp(T* p, bool); + + T* m_ptr; +}; + +#undef COMPARE + +template <typename T> +TextOutput& operator<<(TextOutput& to, const sp<T>& val); + +// --------------------------------------------------------------------------- +// No user serviceable parts below here. + +template<typename T> +sp<T>::sp(T* other) +: m_ptr(other) + { + if (other) other->incStrong(this); + } + +template<typename T> +sp<T>::sp(const sp<T>& other) +: m_ptr(other.m_ptr) + { + if (m_ptr) m_ptr->incStrong(this); + } + +template<typename T> template<typename U> +sp<T>::sp(U* other) : m_ptr(other) +{ + if (other) other->incStrong(this); +} + +template<typename T> template<typename U> +sp<T>::sp(const sp<U>& other) +: m_ptr(other.m_ptr) + { + if (m_ptr) m_ptr->incStrong(this); + } + +template<typename T> +sp<T>::~sp() +{ + if (m_ptr) m_ptr->decStrong(this); +} + +template<typename T> +sp<T>& sp<T>::operator = (const sp<T>& other) { + T* otherPtr(other.m_ptr); + if (otherPtr) otherPtr->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = otherPtr; + return *this; +} + +template<typename T> +sp<T>& sp<T>::operator = (T* other) +{ + if (other) other->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = other; + return *this; +} + +template<typename T> template<typename U> +sp<T>& sp<T>::operator = (const sp<U>& other) +{ + U* otherPtr(other.m_ptr); + if (otherPtr) otherPtr->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = otherPtr; + return *this; +} + +template<typename T> template<typename U> +sp<T>& sp<T>::operator = (U* other) +{ + if (other) other->incStrong(this); + if (m_ptr) m_ptr->decStrong(this); + m_ptr = other; + return *this; +} + +template<typename T> +void sp<T>::force_set(T* other) +{ + other->forceIncStrong(this); + m_ptr = other; +} + +template<typename T> +void sp<T>::clear() +{ + if (m_ptr) { + m_ptr->decStrong(this); + m_ptr = 0; + } +} + +template<typename T> +sp<T>::sp(T* p, bool) +: m_ptr(p) + { + } + +template <typename T> +inline TextOutput& operator<<(TextOutput& to, const sp<T>& val) +{ + return printStrongPointer(to, val.get()); +} + +}; // namespace android + +// --------------------------------------------------------------------------- + +#endif // ANDROID_STRONG_POINTER_H diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h index 2ff2749..a1663f3 100644 --- a/include/utils/TypeHelpers.h +++ b/include/utils/TypeHelpers.h @@ -37,18 +37,6 @@ template <typename T> struct trait_trivial_move { enum { value = false }; }; template <typename T> struct trait_pointer { enum { value = false }; }; template <typename T> struct trait_pointer<T*> { enum { value = true }; }; -// sp<> can be trivially moved -template <typename T> class sp; -template <typename T> struct trait_trivial_move< sp<T> >{ - enum { value = true }; -}; - -// wp<> can be trivially moved -template <typename T> class wp; -template <typename T> struct trait_trivial_move< wp<T> >{ - enum { value = true }; -}; - template <typename TYPE> struct traits { enum { @@ -217,7 +205,6 @@ void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { } } - // --------------------------------------------------------------------------- /* |