1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/omx-plugin/include/ics/utils/RefBase.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,528 @@ 1.4 +/* 1.5 + * Copyright (C) 2005 The Android Open Source Project 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +#ifndef ANDROID_REF_BASE_H 1.21 +#define ANDROID_REF_BASE_H 1.22 + 1.23 +#include <cutils/atomic.h> 1.24 + 1.25 +#include <stdint.h> 1.26 +#include <sys/types.h> 1.27 +#include <stdlib.h> 1.28 +#include <string.h> 1.29 + 1.30 +#include <utils/StrongPointer.h> 1.31 + 1.32 +// --------------------------------------------------------------------------- 1.33 +namespace android { 1.34 + 1.35 +class TextOutput; 1.36 +TextOutput& printWeakPointer(TextOutput& to, const void* val); 1.37 + 1.38 +// --------------------------------------------------------------------------- 1.39 + 1.40 +#define COMPARE_WEAK(_op_) \ 1.41 +inline bool operator _op_ (const sp<T>& o) const { \ 1.42 + return m_ptr _op_ o.m_ptr; \ 1.43 +} \ 1.44 +inline bool operator _op_ (const T* o) const { \ 1.45 + return m_ptr _op_ o; \ 1.46 +} \ 1.47 +template<typename U> \ 1.48 +inline bool operator _op_ (const sp<U>& o) const { \ 1.49 + return m_ptr _op_ o.m_ptr; \ 1.50 +} \ 1.51 +template<typename U> \ 1.52 +inline bool operator _op_ (const U* o) const { \ 1.53 + return m_ptr _op_ o; \ 1.54 +} 1.55 + 1.56 +// --------------------------------------------------------------------------- 1.57 +class ReferenceMover; 1.58 +class ReferenceConverterBase { 1.59 +public: 1.60 + virtual size_t getReferenceTypeSize() const = 0; 1.61 + virtual void* getReferenceBase(void const*) const = 0; 1.62 + inline virtual ~ReferenceConverterBase() { } 1.63 +}; 1.64 + 1.65 +// --------------------------------------------------------------------------- 1.66 + 1.67 +class RefBase 1.68 +{ 1.69 +public: 1.70 + void incStrong(const void* id) const; 1.71 + void decStrong(const void* id) const; 1.72 + 1.73 + void forceIncStrong(const void* id) const; 1.74 + 1.75 + //! DEBUGGING ONLY: Get current strong ref count. 1.76 + int32_t getStrongCount() const; 1.77 + 1.78 + class weakref_type 1.79 + { 1.80 + public: 1.81 + RefBase* refBase() const; 1.82 + 1.83 + void incWeak(const void* id); 1.84 + void decWeak(const void* id); 1.85 + 1.86 + // acquires a strong reference if there is already one. 1.87 + bool attemptIncStrong(const void* id); 1.88 + 1.89 + // acquires a weak reference if there is already one. 1.90 + // This is not always safe. see ProcessState.cpp and BpBinder.cpp 1.91 + // for proper use. 1.92 + bool attemptIncWeak(const void* id); 1.93 + 1.94 + //! DEBUGGING ONLY: Get current weak ref count. 1.95 + int32_t getWeakCount() const; 1.96 + 1.97 + //! DEBUGGING ONLY: Print references held on object. 1.98 + void printRefs() const; 1.99 + 1.100 + //! DEBUGGING ONLY: Enable tracking for this object. 1.101 + // enable -- enable/disable tracking 1.102 + // retain -- when tracking is enable, if true, then we save a stack trace 1.103 + // for each reference and dereference; when retain == false, we 1.104 + // match up references and dereferences and keep only the 1.105 + // outstanding ones. 1.106 + 1.107 + void trackMe(bool enable, bool retain); 1.108 + }; 1.109 + 1.110 + weakref_type* createWeak(const void* id) const; 1.111 + 1.112 + weakref_type* getWeakRefs() const; 1.113 + 1.114 + //! DEBUGGING ONLY: Print references held on object. 1.115 + inline void printRefs() const { getWeakRefs()->printRefs(); } 1.116 + 1.117 + //! DEBUGGING ONLY: Enable tracking of object. 1.118 + inline void trackMe(bool enable, bool retain) 1.119 + { 1.120 + getWeakRefs()->trackMe(enable, retain); 1.121 + } 1.122 + 1.123 + typedef RefBase basetype; 1.124 + 1.125 +protected: 1.126 + RefBase(); 1.127 + virtual ~RefBase(); 1.128 + 1.129 + //! Flags for extendObjectLifetime() 1.130 + enum { 1.131 + OBJECT_LIFETIME_STRONG = 0x0000, 1.132 + OBJECT_LIFETIME_WEAK = 0x0001, 1.133 + OBJECT_LIFETIME_MASK = 0x0001 1.134 + }; 1.135 + 1.136 + void extendObjectLifetime(int32_t mode); 1.137 + 1.138 + //! Flags for onIncStrongAttempted() 1.139 + enum { 1.140 + FIRST_INC_STRONG = 0x0001 1.141 + }; 1.142 + 1.143 + virtual void onFirstRef(); 1.144 + virtual void onLastStrongRef(const void* id); 1.145 + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); 1.146 + virtual void onLastWeakRef(const void* id); 1.147 + 1.148 +private: 1.149 + friend class ReferenceMover; 1.150 + static void moveReferences(void* d, void const* s, size_t n, 1.151 + const ReferenceConverterBase& caster); 1.152 + 1.153 +private: 1.154 + friend class weakref_type; 1.155 + class weakref_impl; 1.156 + 1.157 + RefBase(const RefBase& o); 1.158 + RefBase& operator=(const RefBase& o); 1.159 + 1.160 + weakref_impl* const mRefs; 1.161 +}; 1.162 + 1.163 +// --------------------------------------------------------------------------- 1.164 + 1.165 +template <class T> 1.166 +class LightRefBase 1.167 +{ 1.168 +public: 1.169 + inline LightRefBase() : mCount(0) { } 1.170 + inline void incStrong(const void* id) const { 1.171 + android_atomic_inc(&mCount); 1.172 + } 1.173 + inline void decStrong(const void* id) const { 1.174 + if (android_atomic_dec(&mCount) == 1) { 1.175 + delete static_cast<const T*>(this); 1.176 + } 1.177 + } 1.178 + //! DEBUGGING ONLY: Get current strong ref count. 1.179 + inline int32_t getStrongCount() const { 1.180 + return mCount; 1.181 + } 1.182 + 1.183 + typedef LightRefBase<T> basetype; 1.184 + 1.185 +protected: 1.186 + inline ~LightRefBase() { } 1.187 + 1.188 +private: 1.189 + friend class ReferenceMover; 1.190 + inline static void moveReferences(void* d, void const* s, size_t n, 1.191 + const ReferenceConverterBase& caster) { } 1.192 + 1.193 +private: 1.194 + mutable volatile int32_t mCount; 1.195 +}; 1.196 + 1.197 +// --------------------------------------------------------------------------- 1.198 + 1.199 +template <typename T> 1.200 +class wp 1.201 +{ 1.202 +public: 1.203 + typedef typename RefBase::weakref_type weakref_type; 1.204 + 1.205 + inline wp() : m_ptr(0) { } 1.206 + 1.207 + wp(T* other); 1.208 + wp(const wp<T>& other); 1.209 + wp(const sp<T>& other); 1.210 + template<typename U> wp(U* other); 1.211 + template<typename U> wp(const sp<U>& other); 1.212 + template<typename U> wp(const wp<U>& other); 1.213 + 1.214 + ~wp(); 1.215 + 1.216 + // Assignment 1.217 + 1.218 + wp& operator = (T* other); 1.219 + wp& operator = (const wp<T>& other); 1.220 + wp& operator = (const sp<T>& other); 1.221 + 1.222 + template<typename U> wp& operator = (U* other); 1.223 + template<typename U> wp& operator = (const wp<U>& other); 1.224 + template<typename U> wp& operator = (const sp<U>& other); 1.225 + 1.226 + void set_object_and_refs(T* other, weakref_type* refs); 1.227 + 1.228 + // promotion to sp 1.229 + 1.230 + sp<T> promote() const; 1.231 + 1.232 + // Reset 1.233 + 1.234 + void clear(); 1.235 + 1.236 + // Accessors 1.237 + 1.238 + inline weakref_type* get_refs() const { return m_refs; } 1.239 + 1.240 + inline T* unsafe_get() const { return m_ptr; } 1.241 + 1.242 + // Operators 1.243 + 1.244 + COMPARE_WEAK(==) 1.245 + COMPARE_WEAK(!=) 1.246 + COMPARE_WEAK(>) 1.247 + COMPARE_WEAK(<) 1.248 + COMPARE_WEAK(<=) 1.249 + COMPARE_WEAK(>=) 1.250 + 1.251 + inline bool operator == (const wp<T>& o) const { 1.252 + return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); 1.253 + } 1.254 + template<typename U> 1.255 + inline bool operator == (const wp<U>& o) const { 1.256 + return m_ptr == o.m_ptr; 1.257 + } 1.258 + 1.259 + inline bool operator > (const wp<T>& o) const { 1.260 + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 1.261 + } 1.262 + template<typename U> 1.263 + inline bool operator > (const wp<U>& o) const { 1.264 + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 1.265 + } 1.266 + 1.267 + inline bool operator < (const wp<T>& o) const { 1.268 + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 1.269 + } 1.270 + template<typename U> 1.271 + inline bool operator < (const wp<U>& o) const { 1.272 + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 1.273 + } 1.274 + inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } 1.275 + template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } 1.276 + inline bool operator <= (const wp<T>& o) const { return !operator > (o); } 1.277 + template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } 1.278 + inline bool operator >= (const wp<T>& o) const { return !operator < (o); } 1.279 + template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } 1.280 + 1.281 +private: 1.282 + template<typename Y> friend class sp; 1.283 + template<typename Y> friend class wp; 1.284 + 1.285 + T* m_ptr; 1.286 + weakref_type* m_refs; 1.287 +}; 1.288 + 1.289 +template <typename T> 1.290 +TextOutput& operator<<(TextOutput& to, const wp<T>& val); 1.291 + 1.292 +#undef COMPARE_WEAK 1.293 + 1.294 +// --------------------------------------------------------------------------- 1.295 +// No user serviceable parts below here. 1.296 + 1.297 +template<typename T> 1.298 +wp<T>::wp(T* other) 1.299 + : m_ptr(other) 1.300 +{ 1.301 + if (other) m_refs = other->createWeak(this); 1.302 +} 1.303 + 1.304 +template<typename T> 1.305 +wp<T>::wp(const wp<T>& other) 1.306 + : m_ptr(other.m_ptr), m_refs(other.m_refs) 1.307 +{ 1.308 + if (m_ptr) m_refs->incWeak(this); 1.309 +} 1.310 + 1.311 +template<typename T> 1.312 +wp<T>::wp(const sp<T>& other) 1.313 + : m_ptr(other.m_ptr) 1.314 +{ 1.315 + if (m_ptr) { 1.316 + m_refs = m_ptr->createWeak(this); 1.317 + } 1.318 +} 1.319 + 1.320 +template<typename T> template<typename U> 1.321 +wp<T>::wp(U* other) 1.322 + : m_ptr(other) 1.323 +{ 1.324 + if (other) m_refs = other->createWeak(this); 1.325 +} 1.326 + 1.327 +template<typename T> template<typename U> 1.328 +wp<T>::wp(const wp<U>& other) 1.329 + : m_ptr(other.m_ptr) 1.330 +{ 1.331 + if (m_ptr) { 1.332 + m_refs = other.m_refs; 1.333 + m_refs->incWeak(this); 1.334 + } 1.335 +} 1.336 + 1.337 +template<typename T> template<typename U> 1.338 +wp<T>::wp(const sp<U>& other) 1.339 + : m_ptr(other.m_ptr) 1.340 +{ 1.341 + if (m_ptr) { 1.342 + m_refs = m_ptr->createWeak(this); 1.343 + } 1.344 +} 1.345 + 1.346 +template<typename T> 1.347 +wp<T>::~wp() 1.348 +{ 1.349 + if (m_ptr) m_refs->decWeak(this); 1.350 +} 1.351 + 1.352 +template<typename T> 1.353 +wp<T>& wp<T>::operator = (T* other) 1.354 +{ 1.355 + weakref_type* newRefs = 1.356 + other ? other->createWeak(this) : 0; 1.357 + if (m_ptr) m_refs->decWeak(this); 1.358 + m_ptr = other; 1.359 + m_refs = newRefs; 1.360 + return *this; 1.361 +} 1.362 + 1.363 +template<typename T> 1.364 +wp<T>& wp<T>::operator = (const wp<T>& other) 1.365 +{ 1.366 + weakref_type* otherRefs(other.m_refs); 1.367 + T* otherPtr(other.m_ptr); 1.368 + if (otherPtr) otherRefs->incWeak(this); 1.369 + if (m_ptr) m_refs->decWeak(this); 1.370 + m_ptr = otherPtr; 1.371 + m_refs = otherRefs; 1.372 + return *this; 1.373 +} 1.374 + 1.375 +template<typename T> 1.376 +wp<T>& wp<T>::operator = (const sp<T>& other) 1.377 +{ 1.378 + weakref_type* newRefs = 1.379 + other != NULL ? other->createWeak(this) : 0; 1.380 + T* otherPtr(other.m_ptr); 1.381 + if (m_ptr) m_refs->decWeak(this); 1.382 + m_ptr = otherPtr; 1.383 + m_refs = newRefs; 1.384 + return *this; 1.385 +} 1.386 + 1.387 +template<typename T> template<typename U> 1.388 +wp<T>& wp<T>::operator = (U* other) 1.389 +{ 1.390 + weakref_type* newRefs = 1.391 + other ? other->createWeak(this) : 0; 1.392 + if (m_ptr) m_refs->decWeak(this); 1.393 + m_ptr = other; 1.394 + m_refs = newRefs; 1.395 + return *this; 1.396 +} 1.397 + 1.398 +template<typename T> template<typename U> 1.399 +wp<T>& wp<T>::operator = (const wp<U>& other) 1.400 +{ 1.401 + weakref_type* otherRefs(other.m_refs); 1.402 + U* otherPtr(other.m_ptr); 1.403 + if (otherPtr) otherRefs->incWeak(this); 1.404 + if (m_ptr) m_refs->decWeak(this); 1.405 + m_ptr = otherPtr; 1.406 + m_refs = otherRefs; 1.407 + return *this; 1.408 +} 1.409 + 1.410 +template<typename T> template<typename U> 1.411 +wp<T>& wp<T>::operator = (const sp<U>& other) 1.412 +{ 1.413 + weakref_type* newRefs = 1.414 + other != NULL ? other->createWeak(this) : 0; 1.415 + U* otherPtr(other.m_ptr); 1.416 + if (m_ptr) m_refs->decWeak(this); 1.417 + m_ptr = otherPtr; 1.418 + m_refs = newRefs; 1.419 + return *this; 1.420 +} 1.421 + 1.422 +template<typename T> 1.423 +void wp<T>::set_object_and_refs(T* other, weakref_type* refs) 1.424 +{ 1.425 + if (other) refs->incWeak(this); 1.426 + if (m_ptr) m_refs->decWeak(this); 1.427 + m_ptr = other; 1.428 + m_refs = refs; 1.429 +} 1.430 + 1.431 +template<typename T> 1.432 +sp<T> wp<T>::promote() const 1.433 +{ 1.434 + sp<T> result; 1.435 + if (m_ptr && m_refs->attemptIncStrong(&result)) { 1.436 + result.set_pointer(m_ptr); 1.437 + } 1.438 + return result; 1.439 +} 1.440 + 1.441 +template<typename T> 1.442 +void wp<T>::clear() 1.443 +{ 1.444 + if (m_ptr) { 1.445 + m_refs->decWeak(this); 1.446 + m_ptr = 0; 1.447 + } 1.448 +} 1.449 + 1.450 +template <typename T> 1.451 +inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) 1.452 +{ 1.453 + return printWeakPointer(to, val.unsafe_get()); 1.454 +} 1.455 + 1.456 +// --------------------------------------------------------------------------- 1.457 + 1.458 +// this class just serves as a namespace so TYPE::moveReferences can stay 1.459 +// private. 1.460 + 1.461 +class ReferenceMover { 1.462 + // StrongReferenceCast and WeakReferenceCast do the impedance matching 1.463 + // between the generic (void*) implementation in Refbase and the strongly typed 1.464 + // template specializations below. 1.465 + 1.466 + template <typename TYPE> 1.467 + struct StrongReferenceCast : public ReferenceConverterBase { 1.468 + virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); } 1.469 + virtual void* getReferenceBase(void const* p) const { 1.470 + sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p)); 1.471 + return static_cast<typename TYPE::basetype *>(sptr->get()); 1.472 + } 1.473 + }; 1.474 + 1.475 + template <typename TYPE> 1.476 + struct WeakReferenceCast : public ReferenceConverterBase { 1.477 + virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); } 1.478 + virtual void* getReferenceBase(void const* p) const { 1.479 + wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p)); 1.480 + return static_cast<typename TYPE::basetype *>(sptr->unsafe_get()); 1.481 + } 1.482 + }; 1.483 + 1.484 +public: 1.485 + template<typename TYPE> static inline 1.486 + void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 1.487 + memmove(d, s, n*sizeof(sp<TYPE>)); 1.488 + StrongReferenceCast<TYPE> caster; 1.489 + TYPE::moveReferences(d, s, n, caster); 1.490 + } 1.491 + template<typename TYPE> static inline 1.492 + void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 1.493 + memmove(d, s, n*sizeof(wp<TYPE>)); 1.494 + WeakReferenceCast<TYPE> caster; 1.495 + TYPE::moveReferences(d, s, n, caster); 1.496 + } 1.497 +}; 1.498 + 1.499 +// specialization for moving sp<> and wp<> types. 1.500 +// these are used by the [Sorted|Keyed]Vector<> implementations 1.501 +// sp<> and wp<> need to be handled specially, because they do not 1.502 +// have trivial copy operation in the general case (see RefBase.cpp 1.503 +// when DEBUG ops are enabled), but can be implemented very 1.504 +// efficiently in most cases. 1.505 + 1.506 +template<typename TYPE> inline 1.507 +void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 1.508 + ReferenceMover::move_references(d, s, n); 1.509 +} 1.510 + 1.511 +template<typename TYPE> inline 1.512 +void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 1.513 + ReferenceMover::move_references(d, s, n); 1.514 +} 1.515 + 1.516 +template<typename TYPE> inline 1.517 +void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 1.518 + ReferenceMover::move_references(d, s, n); 1.519 +} 1.520 + 1.521 +template<typename TYPE> inline 1.522 +void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 1.523 + ReferenceMover::move_references(d, s, n); 1.524 +} 1.525 + 1.526 + 1.527 +}; // namespace android 1.528 + 1.529 +// --------------------------------------------------------------------------- 1.530 + 1.531 +#endif // ANDROID_REF_BASE_H