1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/omx-plugin/include/gb/utils/RefBase.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,609 @@ 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 +#include <utils/TextOutput.h> 1.25 + 1.26 +#include <stdint.h> 1.27 +#include <sys/types.h> 1.28 +#include <stdlib.h> 1.29 + 1.30 +// --------------------------------------------------------------------------- 1.31 +namespace android { 1.32 + 1.33 +template<typename T> class wp; 1.34 + 1.35 +// --------------------------------------------------------------------------- 1.36 + 1.37 +#define COMPARE_WEAK(_op_) \ 1.38 +inline bool operator _op_ (const sp<T>& o) const { \ 1.39 + return m_ptr _op_ o.m_ptr; \ 1.40 +} \ 1.41 +inline bool operator _op_ (const T* o) const { \ 1.42 + return m_ptr _op_ o; \ 1.43 +} \ 1.44 +template<typename U> \ 1.45 +inline bool operator _op_ (const sp<U>& o) const { \ 1.46 + return m_ptr _op_ o.m_ptr; \ 1.47 +} \ 1.48 +template<typename U> \ 1.49 +inline bool operator _op_ (const U* o) const { \ 1.50 + return m_ptr _op_ o; \ 1.51 +} 1.52 + 1.53 +#define COMPARE(_op_) \ 1.54 +COMPARE_WEAK(_op_) \ 1.55 +inline bool operator _op_ (const wp<T>& o) const { \ 1.56 + return m_ptr _op_ o.m_ptr; \ 1.57 +} \ 1.58 +template<typename U> \ 1.59 +inline bool operator _op_ (const wp<U>& o) const { \ 1.60 + return m_ptr _op_ o.m_ptr; \ 1.61 +} 1.62 + 1.63 +// --------------------------------------------------------------------------- 1.64 + 1.65 +class RefBase 1.66 +{ 1.67 +public: 1.68 + void incStrong(const void* id) const; 1.69 + void decStrong(const void* id) const; 1.70 + 1.71 + void forceIncStrong(const void* id) const; 1.72 + 1.73 + //! DEBUGGING ONLY: Get current strong ref count. 1.74 + int32_t getStrongCount() const; 1.75 + 1.76 + class weakref_type 1.77 + { 1.78 + public: 1.79 + RefBase* refBase() const; 1.80 + 1.81 + void incWeak(const void* id); 1.82 + void decWeak(const void* id); 1.83 + 1.84 + bool attemptIncStrong(const void* id); 1.85 + 1.86 + //! This is only safe if you have set OBJECT_LIFETIME_FOREVER. 1.87 + bool attemptIncWeak(const void* id); 1.88 + 1.89 + //! DEBUGGING ONLY: Get current weak ref count. 1.90 + int32_t getWeakCount() const; 1.91 + 1.92 + //! DEBUGGING ONLY: Print references held on object. 1.93 + void printRefs() const; 1.94 + 1.95 + //! DEBUGGING ONLY: Enable tracking for this object. 1.96 + // enable -- enable/disable tracking 1.97 + // retain -- when tracking is enable, if true, then we save a stack trace 1.98 + // for each reference and dereference; when retain == false, we 1.99 + // match up references and dereferences and keep only the 1.100 + // outstanding ones. 1.101 + 1.102 + void trackMe(bool enable, bool retain); 1.103 + }; 1.104 + 1.105 + weakref_type* createWeak(const void* id) const; 1.106 + 1.107 + weakref_type* getWeakRefs() const; 1.108 + 1.109 + //! DEBUGGING ONLY: Print references held on object. 1.110 + inline void printRefs() const { getWeakRefs()->printRefs(); } 1.111 + 1.112 + //! DEBUGGING ONLY: Enable tracking of object. 1.113 + inline void trackMe(bool enable, bool retain) 1.114 + { 1.115 + getWeakRefs()->trackMe(enable, retain); 1.116 + } 1.117 + 1.118 + // used to override the RefBase destruction. 1.119 + class Destroyer { 1.120 + friend class RefBase; 1.121 + public: 1.122 + virtual ~Destroyer(); 1.123 + private: 1.124 + virtual void destroy(RefBase const* base) = 0; 1.125 + }; 1.126 + 1.127 + // Make sure to never acquire a strong reference from this function. The 1.128 + // same restrictions than for destructors apply. 1.129 + void setDestroyer(Destroyer* destroyer); 1.130 + 1.131 +protected: 1.132 + RefBase(); 1.133 + virtual ~RefBase(); 1.134 + 1.135 + //! Flags for extendObjectLifetime() 1.136 + enum { 1.137 + OBJECT_LIFETIME_WEAK = 0x0001, 1.138 + OBJECT_LIFETIME_FOREVER = 0x0003 1.139 + }; 1.140 + 1.141 + void extendObjectLifetime(int32_t mode); 1.142 + 1.143 + //! Flags for onIncStrongAttempted() 1.144 + enum { 1.145 + FIRST_INC_STRONG = 0x0001 1.146 + }; 1.147 + 1.148 + virtual void onFirstRef(); 1.149 + virtual void onLastStrongRef(const void* id); 1.150 + virtual bool onIncStrongAttempted(uint32_t flags, const void* id); 1.151 + virtual void onLastWeakRef(const void* id); 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 +protected: 1.184 + inline ~LightRefBase() { } 1.185 + 1.186 +private: 1.187 + mutable volatile int32_t mCount; 1.188 +}; 1.189 + 1.190 +// --------------------------------------------------------------------------- 1.191 + 1.192 +template <typename T> 1.193 +class sp 1.194 +{ 1.195 +public: 1.196 + typedef typename RefBase::weakref_type weakref_type; 1.197 + 1.198 + inline sp() : m_ptr(0) { } 1.199 + 1.200 + sp(T* other); 1.201 + sp(const sp<T>& other); 1.202 + template<typename U> sp(U* other); 1.203 + template<typename U> sp(const sp<U>& other); 1.204 + 1.205 + ~sp(); 1.206 + 1.207 + // Assignment 1.208 + 1.209 + sp& operator = (T* other); 1.210 + sp& operator = (const sp<T>& other); 1.211 + 1.212 + template<typename U> sp& operator = (const sp<U>& other); 1.213 + template<typename U> sp& operator = (U* other); 1.214 + 1.215 + //! Special optimization for use by ProcessState (and nobody else). 1.216 + void force_set(T* other); 1.217 + 1.218 + // Reset 1.219 + 1.220 + void clear(); 1.221 + 1.222 + // Accessors 1.223 + 1.224 + inline T& operator* () const { return *m_ptr; } 1.225 + inline T* operator-> () const { return m_ptr; } 1.226 + inline T* get() const { return m_ptr; } 1.227 + 1.228 + // Operators 1.229 + 1.230 + COMPARE(==) 1.231 + COMPARE(!=) 1.232 + COMPARE(>) 1.233 + COMPARE(<) 1.234 + COMPARE(<=) 1.235 + COMPARE(>=) 1.236 + 1.237 +private: 1.238 + template<typename Y> friend class sp; 1.239 + template<typename Y> friend class wp; 1.240 + 1.241 + // Optimization for wp::promote(). 1.242 + sp(T* p, weakref_type* refs); 1.243 + 1.244 + T* m_ptr; 1.245 +}; 1.246 + 1.247 +template <typename T> 1.248 +TextOutput& operator<<(TextOutput& to, const sp<T>& val); 1.249 + 1.250 +// --------------------------------------------------------------------------- 1.251 + 1.252 +template <typename T> 1.253 +class wp 1.254 +{ 1.255 +public: 1.256 + typedef typename RefBase::weakref_type weakref_type; 1.257 + 1.258 + inline wp() : m_ptr(0) { } 1.259 + 1.260 + wp(T* other); 1.261 + wp(const wp<T>& other); 1.262 + wp(const sp<T>& other); 1.263 + template<typename U> wp(U* other); 1.264 + template<typename U> wp(const sp<U>& other); 1.265 + template<typename U> wp(const wp<U>& other); 1.266 + 1.267 + ~wp(); 1.268 + 1.269 + // Assignment 1.270 + 1.271 + wp& operator = (T* other); 1.272 + wp& operator = (const wp<T>& other); 1.273 + wp& operator = (const sp<T>& other); 1.274 + 1.275 + template<typename U> wp& operator = (U* other); 1.276 + template<typename U> wp& operator = (const wp<U>& other); 1.277 + template<typename U> wp& operator = (const sp<U>& other); 1.278 + 1.279 + void set_object_and_refs(T* other, weakref_type* refs); 1.280 + 1.281 + // promotion to sp 1.282 + 1.283 + sp<T> promote() const; 1.284 + 1.285 + // Reset 1.286 + 1.287 + void clear(); 1.288 + 1.289 + // Accessors 1.290 + 1.291 + inline weakref_type* get_refs() const { return m_refs; } 1.292 + 1.293 + inline T* unsafe_get() const { return m_ptr; } 1.294 + 1.295 + // Operators 1.296 + 1.297 + COMPARE_WEAK(==) 1.298 + COMPARE_WEAK(!=) 1.299 + COMPARE_WEAK(>) 1.300 + COMPARE_WEAK(<) 1.301 + COMPARE_WEAK(<=) 1.302 + COMPARE_WEAK(>=) 1.303 + 1.304 + inline bool operator == (const wp<T>& o) const { 1.305 + return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); 1.306 + } 1.307 + template<typename U> 1.308 + inline bool operator == (const wp<U>& o) const { 1.309 + return m_ptr == o.m_ptr; 1.310 + } 1.311 + 1.312 + inline bool operator > (const wp<T>& o) const { 1.313 + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 1.314 + } 1.315 + template<typename U> 1.316 + inline bool operator > (const wp<U>& o) const { 1.317 + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 1.318 + } 1.319 + 1.320 + inline bool operator < (const wp<T>& o) const { 1.321 + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 1.322 + } 1.323 + template<typename U> 1.324 + inline bool operator < (const wp<U>& o) const { 1.325 + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 1.326 + } 1.327 + inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } 1.328 + template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } 1.329 + inline bool operator <= (const wp<T>& o) const { return !operator > (o); } 1.330 + template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } 1.331 + inline bool operator >= (const wp<T>& o) const { return !operator < (o); } 1.332 + template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } 1.333 + 1.334 +private: 1.335 + template<typename Y> friend class sp; 1.336 + template<typename Y> friend class wp; 1.337 + 1.338 + T* m_ptr; 1.339 + weakref_type* m_refs; 1.340 +}; 1.341 + 1.342 +template <typename T> 1.343 +TextOutput& operator<<(TextOutput& to, const wp<T>& val); 1.344 + 1.345 +#undef COMPARE 1.346 +#undef COMPARE_WEAK 1.347 + 1.348 +// --------------------------------------------------------------------------- 1.349 +// No user serviceable parts below here. 1.350 + 1.351 +template<typename T> 1.352 +sp<T>::sp(T* other) 1.353 + : m_ptr(other) 1.354 +{ 1.355 + if (other) other->incStrong(this); 1.356 +} 1.357 + 1.358 +template<typename T> 1.359 +sp<T>::sp(const sp<T>& other) 1.360 + : m_ptr(other.m_ptr) 1.361 +{ 1.362 + if (m_ptr) m_ptr->incStrong(this); 1.363 +} 1.364 + 1.365 +template<typename T> template<typename U> 1.366 +sp<T>::sp(U* other) : m_ptr(other) 1.367 +{ 1.368 + if (other) other->incStrong(this); 1.369 +} 1.370 + 1.371 +template<typename T> template<typename U> 1.372 +sp<T>::sp(const sp<U>& other) 1.373 + : m_ptr(other.m_ptr) 1.374 +{ 1.375 + if (m_ptr) m_ptr->incStrong(this); 1.376 +} 1.377 + 1.378 +template<typename T> 1.379 +sp<T>::~sp() 1.380 +{ 1.381 + if (m_ptr) m_ptr->decStrong(this); 1.382 +} 1.383 + 1.384 +template<typename T> 1.385 +sp<T>& sp<T>::operator = (const sp<T>& other) { 1.386 + T* otherPtr(other.m_ptr); 1.387 + if (otherPtr) otherPtr->incStrong(this); 1.388 + if (m_ptr) m_ptr->decStrong(this); 1.389 + m_ptr = otherPtr; 1.390 + return *this; 1.391 +} 1.392 + 1.393 +template<typename T> 1.394 +sp<T>& sp<T>::operator = (T* other) 1.395 +{ 1.396 + if (other) other->incStrong(this); 1.397 + if (m_ptr) m_ptr->decStrong(this); 1.398 + m_ptr = other; 1.399 + return *this; 1.400 +} 1.401 + 1.402 +template<typename T> template<typename U> 1.403 +sp<T>& sp<T>::operator = (const sp<U>& other) 1.404 +{ 1.405 + U* otherPtr(other.m_ptr); 1.406 + if (otherPtr) otherPtr->incStrong(this); 1.407 + if (m_ptr) m_ptr->decStrong(this); 1.408 + m_ptr = otherPtr; 1.409 + return *this; 1.410 +} 1.411 + 1.412 +template<typename T> template<typename U> 1.413 +sp<T>& sp<T>::operator = (U* other) 1.414 +{ 1.415 + if (other) other->incStrong(this); 1.416 + if (m_ptr) m_ptr->decStrong(this); 1.417 + m_ptr = other; 1.418 + return *this; 1.419 +} 1.420 + 1.421 +template<typename T> 1.422 +void sp<T>::force_set(T* other) 1.423 +{ 1.424 + other->forceIncStrong(this); 1.425 + m_ptr = other; 1.426 +} 1.427 + 1.428 +template<typename T> 1.429 +void sp<T>::clear() 1.430 +{ 1.431 + if (m_ptr) { 1.432 + m_ptr->decStrong(this); 1.433 + m_ptr = 0; 1.434 + } 1.435 +} 1.436 + 1.437 +template<typename T> 1.438 +sp<T>::sp(T* p, weakref_type* refs) 1.439 + : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0) 1.440 +{ 1.441 +} 1.442 + 1.443 +template <typename T> 1.444 +inline TextOutput& operator<<(TextOutput& to, const sp<T>& val) 1.445 +{ 1.446 + to << "sp<>(" << val.get() << ")"; 1.447 + return to; 1.448 +} 1.449 + 1.450 +// --------------------------------------------------------------------------- 1.451 + 1.452 +template<typename T> 1.453 +wp<T>::wp(T* other) 1.454 + : m_ptr(other) 1.455 +{ 1.456 + if (other) m_refs = other->createWeak(this); 1.457 +} 1.458 + 1.459 +template<typename T> 1.460 +wp<T>::wp(const wp<T>& other) 1.461 + : m_ptr(other.m_ptr), m_refs(other.m_refs) 1.462 +{ 1.463 + if (m_ptr) m_refs->incWeak(this); 1.464 +} 1.465 + 1.466 +template<typename T> 1.467 +wp<T>::wp(const sp<T>& other) 1.468 + : m_ptr(other.m_ptr) 1.469 +{ 1.470 + if (m_ptr) { 1.471 + m_refs = m_ptr->createWeak(this); 1.472 + } 1.473 +} 1.474 + 1.475 +template<typename T> template<typename U> 1.476 +wp<T>::wp(U* other) 1.477 + : m_ptr(other) 1.478 +{ 1.479 + if (other) m_refs = other->createWeak(this); 1.480 +} 1.481 + 1.482 +template<typename T> template<typename U> 1.483 +wp<T>::wp(const wp<U>& other) 1.484 + : m_ptr(other.m_ptr) 1.485 +{ 1.486 + if (m_ptr) { 1.487 + m_refs = other.m_refs; 1.488 + m_refs->incWeak(this); 1.489 + } 1.490 +} 1.491 + 1.492 +template<typename T> template<typename U> 1.493 +wp<T>::wp(const sp<U>& other) 1.494 + : m_ptr(other.m_ptr) 1.495 +{ 1.496 + if (m_ptr) { 1.497 + m_refs = m_ptr->createWeak(this); 1.498 + } 1.499 +} 1.500 + 1.501 +template<typename T> 1.502 +wp<T>::~wp() 1.503 +{ 1.504 + if (m_ptr) m_refs->decWeak(this); 1.505 +} 1.506 + 1.507 +template<typename T> 1.508 +wp<T>& wp<T>::operator = (T* other) 1.509 +{ 1.510 + weakref_type* newRefs = 1.511 + other ? other->createWeak(this) : 0; 1.512 + if (m_ptr) m_refs->decWeak(this); 1.513 + m_ptr = other; 1.514 + m_refs = newRefs; 1.515 + return *this; 1.516 +} 1.517 + 1.518 +template<typename T> 1.519 +wp<T>& wp<T>::operator = (const wp<T>& other) 1.520 +{ 1.521 + weakref_type* otherRefs(other.m_refs); 1.522 + T* otherPtr(other.m_ptr); 1.523 + if (otherPtr) otherRefs->incWeak(this); 1.524 + if (m_ptr) m_refs->decWeak(this); 1.525 + m_ptr = otherPtr; 1.526 + m_refs = otherRefs; 1.527 + return *this; 1.528 +} 1.529 + 1.530 +template<typename T> 1.531 +wp<T>& wp<T>::operator = (const sp<T>& other) 1.532 +{ 1.533 + weakref_type* newRefs = 1.534 + other != NULL ? other->createWeak(this) : 0; 1.535 + T* otherPtr(other.m_ptr); 1.536 + if (m_ptr) m_refs->decWeak(this); 1.537 + m_ptr = otherPtr; 1.538 + m_refs = newRefs; 1.539 + return *this; 1.540 +} 1.541 + 1.542 +template<typename T> template<typename U> 1.543 +wp<T>& wp<T>::operator = (U* other) 1.544 +{ 1.545 + weakref_type* newRefs = 1.546 + other ? other->createWeak(this) : 0; 1.547 + if (m_ptr) m_refs->decWeak(this); 1.548 + m_ptr = other; 1.549 + m_refs = newRefs; 1.550 + return *this; 1.551 +} 1.552 + 1.553 +template<typename T> template<typename U> 1.554 +wp<T>& wp<T>::operator = (const wp<U>& other) 1.555 +{ 1.556 + weakref_type* otherRefs(other.m_refs); 1.557 + U* otherPtr(other.m_ptr); 1.558 + if (otherPtr) otherRefs->incWeak(this); 1.559 + if (m_ptr) m_refs->decWeak(this); 1.560 + m_ptr = otherPtr; 1.561 + m_refs = otherRefs; 1.562 + return *this; 1.563 +} 1.564 + 1.565 +template<typename T> template<typename U> 1.566 +wp<T>& wp<T>::operator = (const sp<U>& other) 1.567 +{ 1.568 + weakref_type* newRefs = 1.569 + other != NULL ? other->createWeak(this) : 0; 1.570 + U* otherPtr(other.m_ptr); 1.571 + if (m_ptr) m_refs->decWeak(this); 1.572 + m_ptr = otherPtr; 1.573 + m_refs = newRefs; 1.574 + return *this; 1.575 +} 1.576 + 1.577 +template<typename T> 1.578 +void wp<T>::set_object_and_refs(T* other, weakref_type* refs) 1.579 +{ 1.580 + if (other) refs->incWeak(this); 1.581 + if (m_ptr) m_refs->decWeak(this); 1.582 + m_ptr = other; 1.583 + m_refs = refs; 1.584 +} 1.585 + 1.586 +template<typename T> 1.587 +sp<T> wp<T>::promote() const 1.588 +{ 1.589 + return sp<T>(m_ptr, m_refs); 1.590 +} 1.591 + 1.592 +template<typename T> 1.593 +void wp<T>::clear() 1.594 +{ 1.595 + if (m_ptr) { 1.596 + m_refs->decWeak(this); 1.597 + m_ptr = 0; 1.598 + } 1.599 +} 1.600 + 1.601 +template <typename T> 1.602 +inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) 1.603 +{ 1.604 + to << "wp<>(" << val.unsafe_get() << ")"; 1.605 + return to; 1.606 +} 1.607 + 1.608 +}; // namespace android 1.609 + 1.610 +// --------------------------------------------------------------------------- 1.611 + 1.612 +#endif // ANDROID_REF_BASE_H