media/omx-plugin/include/froyo/utils/RefBase.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright (C) 2005 The Android Open Source Project
michael@0 3 *
michael@0 4 * Licensed under the Apache License, Version 2.0 (the "License");
michael@0 5 * you may not use this file except in compliance with the License.
michael@0 6 * You may obtain a copy of the License at
michael@0 7 *
michael@0 8 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 9 *
michael@0 10 * Unless required by applicable law or agreed to in writing, software
michael@0 11 * distributed under the License is distributed on an "AS IS" BASIS,
michael@0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 13 * See the License for the specific language governing permissions and
michael@0 14 * limitations under the License.
michael@0 15 */
michael@0 16
michael@0 17 #ifndef ANDROID_REF_BASE_H
michael@0 18 #define ANDROID_REF_BASE_H
michael@0 19
michael@0 20 #include <cutils/atomic.h>
michael@0 21 #include <utils/TextOutput.h>
michael@0 22
michael@0 23 #include <stdint.h>
michael@0 24 #include <sys/types.h>
michael@0 25 #include <stdlib.h>
michael@0 26
michael@0 27 // ---------------------------------------------------------------------------
michael@0 28 namespace android {
michael@0 29
michael@0 30 template<typename T> class wp;
michael@0 31
michael@0 32 // ---------------------------------------------------------------------------
michael@0 33
michael@0 34 #define COMPARE(_op_) \
michael@0 35 inline bool operator _op_ (const sp<T>& o) const { \
michael@0 36 return m_ptr _op_ o.m_ptr; \
michael@0 37 } \
michael@0 38 inline bool operator _op_ (const wp<T>& o) const { \
michael@0 39 return m_ptr _op_ o.m_ptr; \
michael@0 40 } \
michael@0 41 inline bool operator _op_ (const T* o) const { \
michael@0 42 return m_ptr _op_ o; \
michael@0 43 } \
michael@0 44 template<typename U> \
michael@0 45 inline bool operator _op_ (const sp<U>& o) const { \
michael@0 46 return m_ptr _op_ o.m_ptr; \
michael@0 47 } \
michael@0 48 template<typename U> \
michael@0 49 inline bool operator _op_ (const wp<U>& o) const { \
michael@0 50 return m_ptr _op_ o.m_ptr; \
michael@0 51 } \
michael@0 52 template<typename U> \
michael@0 53 inline bool operator _op_ (const U* o) const { \
michael@0 54 return m_ptr _op_ o; \
michael@0 55 }
michael@0 56
michael@0 57 // ---------------------------------------------------------------------------
michael@0 58
michael@0 59 class RefBase
michael@0 60 {
michael@0 61 public:
michael@0 62 void incStrong(const void* id) const;
michael@0 63 void decStrong(const void* id) const;
michael@0 64
michael@0 65 void forceIncStrong(const void* id) const;
michael@0 66
michael@0 67 //! DEBUGGING ONLY: Get current strong ref count.
michael@0 68 int32_t getStrongCount() const;
michael@0 69
michael@0 70 class weakref_type
michael@0 71 {
michael@0 72 public:
michael@0 73 RefBase* refBase() const;
michael@0 74
michael@0 75 void incWeak(const void* id);
michael@0 76 void decWeak(const void* id);
michael@0 77
michael@0 78 bool attemptIncStrong(const void* id);
michael@0 79
michael@0 80 //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
michael@0 81 bool attemptIncWeak(const void* id);
michael@0 82
michael@0 83 //! DEBUGGING ONLY: Get current weak ref count.
michael@0 84 int32_t getWeakCount() const;
michael@0 85
michael@0 86 //! DEBUGGING ONLY: Print references held on object.
michael@0 87 void printRefs() const;
michael@0 88
michael@0 89 //! DEBUGGING ONLY: Enable tracking for this object.
michael@0 90 // enable -- enable/disable tracking
michael@0 91 // retain -- when tracking is enable, if true, then we save a stack trace
michael@0 92 // for each reference and dereference; when retain == false, we
michael@0 93 // match up references and dereferences and keep only the
michael@0 94 // outstanding ones.
michael@0 95
michael@0 96 void trackMe(bool enable, bool retain);
michael@0 97 };
michael@0 98
michael@0 99 weakref_type* createWeak(const void* id) const;
michael@0 100
michael@0 101 weakref_type* getWeakRefs() const;
michael@0 102
michael@0 103 //! DEBUGGING ONLY: Print references held on object.
michael@0 104 inline void printRefs() const { getWeakRefs()->printRefs(); }
michael@0 105
michael@0 106 //! DEBUGGING ONLY: Enable tracking of object.
michael@0 107 inline void trackMe(bool enable, bool retain)
michael@0 108 {
michael@0 109 getWeakRefs()->trackMe(enable, retain);
michael@0 110 }
michael@0 111
michael@0 112 protected:
michael@0 113 RefBase();
michael@0 114 virtual ~RefBase();
michael@0 115
michael@0 116 //! Flags for extendObjectLifetime()
michael@0 117 enum {
michael@0 118 OBJECT_LIFETIME_WEAK = 0x0001,
michael@0 119 OBJECT_LIFETIME_FOREVER = 0x0003
michael@0 120 };
michael@0 121
michael@0 122 void extendObjectLifetime(int32_t mode);
michael@0 123
michael@0 124 //! Flags for onIncStrongAttempted()
michael@0 125 enum {
michael@0 126 FIRST_INC_STRONG = 0x0001
michael@0 127 };
michael@0 128
michael@0 129 virtual void onFirstRef();
michael@0 130 virtual void onLastStrongRef(const void* id);
michael@0 131 virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
michael@0 132 virtual void onLastWeakRef(const void* id);
michael@0 133
michael@0 134 private:
michael@0 135 friend class weakref_type;
michael@0 136 class weakref_impl;
michael@0 137
michael@0 138 RefBase(const RefBase& o);
michael@0 139 RefBase& operator=(const RefBase& o);
michael@0 140
michael@0 141 weakref_impl* const mRefs;
michael@0 142 };
michael@0 143
michael@0 144 // ---------------------------------------------------------------------------
michael@0 145
michael@0 146 template <class T>
michael@0 147 class LightRefBase
michael@0 148 {
michael@0 149 public:
michael@0 150 inline LightRefBase() : mCount(0) { }
michael@0 151 inline void incStrong(const void* id) const {
michael@0 152 android_atomic_inc(&mCount);
michael@0 153 }
michael@0 154 inline void decStrong(const void* id) const {
michael@0 155 if (android_atomic_dec(&mCount) == 1) {
michael@0 156 delete static_cast<const T*>(this);
michael@0 157 }
michael@0 158 }
michael@0 159 //! DEBUGGING ONLY: Get current strong ref count.
michael@0 160 inline int32_t getStrongCount() const {
michael@0 161 return mCount;
michael@0 162 }
michael@0 163
michael@0 164 protected:
michael@0 165 inline ~LightRefBase() { }
michael@0 166
michael@0 167 private:
michael@0 168 mutable volatile int32_t mCount;
michael@0 169 };
michael@0 170
michael@0 171 // ---------------------------------------------------------------------------
michael@0 172
michael@0 173 template <typename T>
michael@0 174 class sp
michael@0 175 {
michael@0 176 public:
michael@0 177 typedef typename RefBase::weakref_type weakref_type;
michael@0 178
michael@0 179 inline sp() : m_ptr(0) { }
michael@0 180
michael@0 181 sp(T* other);
michael@0 182 sp(const sp<T>& other);
michael@0 183 template<typename U> sp(U* other);
michael@0 184 template<typename U> sp(const sp<U>& other);
michael@0 185
michael@0 186 ~sp();
michael@0 187
michael@0 188 // Assignment
michael@0 189
michael@0 190 sp& operator = (T* other);
michael@0 191 sp& operator = (const sp<T>& other);
michael@0 192
michael@0 193 template<typename U> sp& operator = (const sp<U>& other);
michael@0 194 template<typename U> sp& operator = (U* other);
michael@0 195
michael@0 196 //! Special optimization for use by ProcessState (and nobody else).
michael@0 197 void force_set(T* other);
michael@0 198
michael@0 199 // Reset
michael@0 200
michael@0 201 void clear();
michael@0 202
michael@0 203 // Accessors
michael@0 204
michael@0 205 inline T& operator* () const { return *m_ptr; }
michael@0 206 inline T* operator-> () const { return m_ptr; }
michael@0 207 inline T* get() const { return m_ptr; }
michael@0 208
michael@0 209 // Operators
michael@0 210
michael@0 211 COMPARE(==)
michael@0 212 COMPARE(!=)
michael@0 213 COMPARE(>)
michael@0 214 COMPARE(<)
michael@0 215 COMPARE(<=)
michael@0 216 COMPARE(>=)
michael@0 217
michael@0 218 private:
michael@0 219 template<typename Y> friend class sp;
michael@0 220 template<typename Y> friend class wp;
michael@0 221
michael@0 222 // Optimization for wp::promote().
michael@0 223 sp(T* p, weakref_type* refs);
michael@0 224
michael@0 225 T* m_ptr;
michael@0 226 };
michael@0 227
michael@0 228 template <typename T>
michael@0 229 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
michael@0 230
michael@0 231 // ---------------------------------------------------------------------------
michael@0 232
michael@0 233 template <typename T>
michael@0 234 class wp
michael@0 235 {
michael@0 236 public:
michael@0 237 typedef typename RefBase::weakref_type weakref_type;
michael@0 238
michael@0 239 inline wp() : m_ptr(0) { }
michael@0 240
michael@0 241 wp(T* other);
michael@0 242 wp(const wp<T>& other);
michael@0 243 wp(const sp<T>& other);
michael@0 244 template<typename U> wp(U* other);
michael@0 245 template<typename U> wp(const sp<U>& other);
michael@0 246 template<typename U> wp(const wp<U>& other);
michael@0 247
michael@0 248 ~wp();
michael@0 249
michael@0 250 // Assignment
michael@0 251
michael@0 252 wp& operator = (T* other);
michael@0 253 wp& operator = (const wp<T>& other);
michael@0 254 wp& operator = (const sp<T>& other);
michael@0 255
michael@0 256 template<typename U> wp& operator = (U* other);
michael@0 257 template<typename U> wp& operator = (const wp<U>& other);
michael@0 258 template<typename U> wp& operator = (const sp<U>& other);
michael@0 259
michael@0 260 void set_object_and_refs(T* other, weakref_type* refs);
michael@0 261
michael@0 262 // promotion to sp
michael@0 263
michael@0 264 sp<T> promote() const;
michael@0 265
michael@0 266 // Reset
michael@0 267
michael@0 268 void clear();
michael@0 269
michael@0 270 // Accessors
michael@0 271
michael@0 272 inline weakref_type* get_refs() const { return m_refs; }
michael@0 273
michael@0 274 inline T* unsafe_get() const { return m_ptr; }
michael@0 275
michael@0 276 // Operators
michael@0 277
michael@0 278 COMPARE(==)
michael@0 279 COMPARE(!=)
michael@0 280 COMPARE(>)
michael@0 281 COMPARE(<)
michael@0 282 COMPARE(<=)
michael@0 283 COMPARE(>=)
michael@0 284
michael@0 285 private:
michael@0 286 template<typename Y> friend class sp;
michael@0 287 template<typename Y> friend class wp;
michael@0 288
michael@0 289 T* m_ptr;
michael@0 290 weakref_type* m_refs;
michael@0 291 };
michael@0 292
michael@0 293 template <typename T>
michael@0 294 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
michael@0 295
michael@0 296 #undef COMPARE
michael@0 297
michael@0 298 // ---------------------------------------------------------------------------
michael@0 299 // No user serviceable parts below here.
michael@0 300
michael@0 301 template<typename T>
michael@0 302 sp<T>::sp(T* other)
michael@0 303 : m_ptr(other)
michael@0 304 {
michael@0 305 if (other) other->incStrong(this);
michael@0 306 }
michael@0 307
michael@0 308 template<typename T>
michael@0 309 sp<T>::sp(const sp<T>& other)
michael@0 310 : m_ptr(other.m_ptr)
michael@0 311 {
michael@0 312 if (m_ptr) m_ptr->incStrong(this);
michael@0 313 }
michael@0 314
michael@0 315 template<typename T> template<typename U>
michael@0 316 sp<T>::sp(U* other) : m_ptr(other)
michael@0 317 {
michael@0 318 if (other) other->incStrong(this);
michael@0 319 }
michael@0 320
michael@0 321 template<typename T> template<typename U>
michael@0 322 sp<T>::sp(const sp<U>& other)
michael@0 323 : m_ptr(other.m_ptr)
michael@0 324 {
michael@0 325 if (m_ptr) m_ptr->incStrong(this);
michael@0 326 }
michael@0 327
michael@0 328 template<typename T>
michael@0 329 sp<T>::~sp()
michael@0 330 {
michael@0 331 if (m_ptr) m_ptr->decStrong(this);
michael@0 332 }
michael@0 333
michael@0 334 template<typename T>
michael@0 335 sp<T>& sp<T>::operator = (const sp<T>& other) {
michael@0 336 if (other.m_ptr) other.m_ptr->incStrong(this);
michael@0 337 if (m_ptr) m_ptr->decStrong(this);
michael@0 338 m_ptr = other.m_ptr;
michael@0 339 return *this;
michael@0 340 }
michael@0 341
michael@0 342 template<typename T>
michael@0 343 sp<T>& sp<T>::operator = (T* other)
michael@0 344 {
michael@0 345 if (other) other->incStrong(this);
michael@0 346 if (m_ptr) m_ptr->decStrong(this);
michael@0 347 m_ptr = other;
michael@0 348 return *this;
michael@0 349 }
michael@0 350
michael@0 351 template<typename T> template<typename U>
michael@0 352 sp<T>& sp<T>::operator = (const sp<U>& other)
michael@0 353 {
michael@0 354 if (other.m_ptr) other.m_ptr->incStrong(this);
michael@0 355 if (m_ptr) m_ptr->decStrong(this);
michael@0 356 m_ptr = other.m_ptr;
michael@0 357 return *this;
michael@0 358 }
michael@0 359
michael@0 360 template<typename T> template<typename U>
michael@0 361 sp<T>& sp<T>::operator = (U* other)
michael@0 362 {
michael@0 363 if (other) other->incStrong(this);
michael@0 364 if (m_ptr) m_ptr->decStrong(this);
michael@0 365 m_ptr = other;
michael@0 366 return *this;
michael@0 367 }
michael@0 368
michael@0 369 template<typename T>
michael@0 370 void sp<T>::force_set(T* other)
michael@0 371 {
michael@0 372 other->forceIncStrong(this);
michael@0 373 m_ptr = other;
michael@0 374 }
michael@0 375
michael@0 376 template<typename T>
michael@0 377 void sp<T>::clear()
michael@0 378 {
michael@0 379 if (m_ptr) {
michael@0 380 m_ptr->decStrong(this);
michael@0 381 m_ptr = 0;
michael@0 382 }
michael@0 383 }
michael@0 384
michael@0 385 template<typename T>
michael@0 386 sp<T>::sp(T* p, weakref_type* refs)
michael@0 387 : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
michael@0 388 {
michael@0 389 }
michael@0 390
michael@0 391 template <typename T>
michael@0 392 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
michael@0 393 {
michael@0 394 to << "sp<>(" << val.get() << ")";
michael@0 395 return to;
michael@0 396 }
michael@0 397
michael@0 398 // ---------------------------------------------------------------------------
michael@0 399
michael@0 400 template<typename T>
michael@0 401 wp<T>::wp(T* other)
michael@0 402 : m_ptr(other)
michael@0 403 {
michael@0 404 if (other) m_refs = other->createWeak(this);
michael@0 405 }
michael@0 406
michael@0 407 template<typename T>
michael@0 408 wp<T>::wp(const wp<T>& other)
michael@0 409 : m_ptr(other.m_ptr), m_refs(other.m_refs)
michael@0 410 {
michael@0 411 if (m_ptr) m_refs->incWeak(this);
michael@0 412 }
michael@0 413
michael@0 414 template<typename T>
michael@0 415 wp<T>::wp(const sp<T>& other)
michael@0 416 : m_ptr(other.m_ptr)
michael@0 417 {
michael@0 418 if (m_ptr) {
michael@0 419 m_refs = m_ptr->createWeak(this);
michael@0 420 }
michael@0 421 }
michael@0 422
michael@0 423 template<typename T> template<typename U>
michael@0 424 wp<T>::wp(U* other)
michael@0 425 : m_ptr(other)
michael@0 426 {
michael@0 427 if (other) m_refs = other->createWeak(this);
michael@0 428 }
michael@0 429
michael@0 430 template<typename T> template<typename U>
michael@0 431 wp<T>::wp(const wp<U>& other)
michael@0 432 : m_ptr(other.m_ptr)
michael@0 433 {
michael@0 434 if (m_ptr) {
michael@0 435 m_refs = other.m_refs;
michael@0 436 m_refs->incWeak(this);
michael@0 437 }
michael@0 438 }
michael@0 439
michael@0 440 template<typename T> template<typename U>
michael@0 441 wp<T>::wp(const sp<U>& other)
michael@0 442 : m_ptr(other.m_ptr)
michael@0 443 {
michael@0 444 if (m_ptr) {
michael@0 445 m_refs = m_ptr->createWeak(this);
michael@0 446 }
michael@0 447 }
michael@0 448
michael@0 449 template<typename T>
michael@0 450 wp<T>::~wp()
michael@0 451 {
michael@0 452 if (m_ptr) m_refs->decWeak(this);
michael@0 453 }
michael@0 454
michael@0 455 template<typename T>
michael@0 456 wp<T>& wp<T>::operator = (T* other)
michael@0 457 {
michael@0 458 weakref_type* newRefs =
michael@0 459 other ? other->createWeak(this) : 0;
michael@0 460 if (m_ptr) m_refs->decWeak(this);
michael@0 461 m_ptr = other;
michael@0 462 m_refs = newRefs;
michael@0 463 return *this;
michael@0 464 }
michael@0 465
michael@0 466 template<typename T>
michael@0 467 wp<T>& wp<T>::operator = (const wp<T>& other)
michael@0 468 {
michael@0 469 if (other.m_ptr) other.m_refs->incWeak(this);
michael@0 470 if (m_ptr) m_refs->decWeak(this);
michael@0 471 m_ptr = other.m_ptr;
michael@0 472 m_refs = other.m_refs;
michael@0 473 return *this;
michael@0 474 }
michael@0 475
michael@0 476 template<typename T>
michael@0 477 wp<T>& wp<T>::operator = (const sp<T>& other)
michael@0 478 {
michael@0 479 weakref_type* newRefs =
michael@0 480 other != NULL ? other->createWeak(this) : 0;
michael@0 481 if (m_ptr) m_refs->decWeak(this);
michael@0 482 m_ptr = other.get();
michael@0 483 m_refs = newRefs;
michael@0 484 return *this;
michael@0 485 }
michael@0 486
michael@0 487 template<typename T> template<typename U>
michael@0 488 wp<T>& wp<T>::operator = (U* other)
michael@0 489 {
michael@0 490 weakref_type* newRefs =
michael@0 491 other ? other->createWeak(this) : 0;
michael@0 492 if (m_ptr) m_refs->decWeak(this);
michael@0 493 m_ptr = other;
michael@0 494 m_refs = newRefs;
michael@0 495 return *this;
michael@0 496 }
michael@0 497
michael@0 498 template<typename T> template<typename U>
michael@0 499 wp<T>& wp<T>::operator = (const wp<U>& other)
michael@0 500 {
michael@0 501 if (other.m_ptr) other.m_refs->incWeak(this);
michael@0 502 if (m_ptr) m_refs->decWeak(this);
michael@0 503 m_ptr = other.m_ptr;
michael@0 504 m_refs = other.m_refs;
michael@0 505 return *this;
michael@0 506 }
michael@0 507
michael@0 508 template<typename T> template<typename U>
michael@0 509 wp<T>& wp<T>::operator = (const sp<U>& other)
michael@0 510 {
michael@0 511 weakref_type* newRefs =
michael@0 512 other != NULL ? other->createWeak(this) : 0;
michael@0 513 if (m_ptr) m_refs->decWeak(this);
michael@0 514 m_ptr = other.get();
michael@0 515 m_refs = newRefs;
michael@0 516 return *this;
michael@0 517 }
michael@0 518
michael@0 519 template<typename T>
michael@0 520 void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
michael@0 521 {
michael@0 522 if (other) refs->incWeak(this);
michael@0 523 if (m_ptr) m_refs->decWeak(this);
michael@0 524 m_ptr = other;
michael@0 525 m_refs = refs;
michael@0 526 }
michael@0 527
michael@0 528 template<typename T>
michael@0 529 sp<T> wp<T>::promote() const
michael@0 530 {
michael@0 531 return sp<T>(m_ptr, m_refs);
michael@0 532 }
michael@0 533
michael@0 534 template<typename T>
michael@0 535 void wp<T>::clear()
michael@0 536 {
michael@0 537 if (m_ptr) {
michael@0 538 m_refs->decWeak(this);
michael@0 539 m_ptr = 0;
michael@0 540 }
michael@0 541 }
michael@0 542
michael@0 543 template <typename T>
michael@0 544 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
michael@0 545 {
michael@0 546 to << "wp<>(" << val.unsafe_get() << ")";
michael@0 547 return to;
michael@0 548 }
michael@0 549
michael@0 550 }; // namespace android
michael@0 551
michael@0 552 // ---------------------------------------------------------------------------
michael@0 553
michael@0 554 #endif // ANDROID_REF_BASE_H

mercurial