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