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