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