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 22 #include <stdint.h> 23 #include <sys/types.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 #include <utils/StrongPointer.h> 28 #include <utils/TypeHelpers.h> 29 30 // --------------------------------------------------------------------------- 31 namespace android { 32 33 class TextOutput; 34 TextOutput& printWeakPointer(TextOutput& to, const void* val); 35 36 // --------------------------------------------------------------------------- 37 38 #define COMPARE_WEAK(_op_) \ 39 inline bool operator _op_ (const sp<T>& o) const { \ 40 return m_ptr _op_ o.m_ptr; \ 41 } \ 42 inline bool operator _op_ (const T* o) const { \ 43 return m_ptr _op_ o; \ 44 } \ 45 template<typename U> \ 46 inline bool operator _op_ (const sp<U>& o) const { \ 47 return m_ptr _op_ o.m_ptr; \ 48 } \ 49 template<typename U> \ 50 inline bool operator _op_ (const U* o) const { \ 51 return m_ptr _op_ o; \ 52 } 53 54 // --------------------------------------------------------------------------- 55 56 class ReferenceRenamer { 57 protected: 58 // destructor is purposedly not virtual so we avoid code overhead from 59 // subclasses; we have to make it protected to guarantee that it 60 // cannot be called from this base class (and to make strict compilers 61 // happy). 62 ~ReferenceRenamer() { } 63 public: 64 virtual void operator()(size_t i) const = 0; 65 }; 66 67 // --------------------------------------------------------------------------- 68 69 class RefBase 70 { 71 public: 72 void incStrong(const void* id) const; 73 void decStrong(const void* id) const; 74 75 void forceIncStrong(const void* id) const; 76 77 //! DEBUGGING ONLY: Get current strong ref count. 78 int32_t getStrongCount() const; 79 80 class weakref_type 81 { 82 public: 83 RefBase* refBase() const; 84 85 void incWeak(const void* id); 86 void decWeak(const void* id); 87 88 // acquires a strong reference if there is already one. 89 bool attemptIncStrong(const void* id); 90 91 // acquires a weak reference if there is already one. 92 // This is not always safe. see ProcessState.cpp and BpBinder.cpp 93 // for proper use. 94 bool attemptIncWeak(const void* id); 95 96 //! DEBUGGING ONLY: Get current weak ref count. 97 int32_t getWeakCount() const; 98 99 //! DEBUGGING ONLY: Print references held on object. 100 void printRefs() const; 101 102 //! DEBUGGING ONLY: Enable tracking for this object. 103 // enable -- enable/disable tracking 104 // retain -- when tracking is enable, if true, then we save a stack trace 105 // for each reference and dereference; when retain == false, we 106 // match up references and dereferences and keep only the 107 // outstanding ones. 108 109 void trackMe(bool enable, bool retain); 110 }; 111 112 weakref_type* createWeak(const void* id) const; 113 114 weakref_type* getWeakRefs() const; 115 116 //! DEBUGGING ONLY: Print references held on object. 117 inline void printRefs() const { getWeakRefs()->printRefs(); } 118 119 //! DEBUGGING ONLY: Enable tracking of object. 120 inline void trackMe(bool enable, bool retain) 121 { 122 getWeakRefs()->trackMe(enable, retain); 123 } 124 125 typedef RefBase basetype; 126 127 protected: 128 RefBase(); 129 virtual ~RefBase(); 130 131 //! Flags for extendObjectLifetime() 132 enum { 133 OBJECT_LIFETIME_STRONG = 0x0000, 134 OBJECT_LIFETIME_WEAK = 0x0001, 135 OBJECT_LIFETIME_MASK = 0x0001 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 private: 158 friend class ReferenceMover; 159 160 static void renameRefs(size_t n, const ReferenceRenamer& renamer); 161 162 static void renameRefId(weakref_type* ref, 163 const void* old_id, const void* new_id); 164 165 static void renameRefId(RefBase* ref, 166 const void* old_id, const void* new_id); 167 168 weakref_impl* const mRefs; 169 }; 170 171 // --------------------------------------------------------------------------- 172 173 template <class T> 174 class LightRefBase 175 { 176 public: 177 inline LightRefBase() : mCount(0) { } 178 inline void incStrong(__attribute__((unused)) const void* id) const { 179 android_atomic_inc(&mCount); 180 } 181 inline void decStrong(__attribute__((unused)) const void* id) const { 182 if (android_atomic_dec(&mCount) == 1) { 183 delete static_cast<const T*>(this); 184 } 185 } 186 //! DEBUGGING ONLY: Get current strong ref count. 187 inline int32_t getStrongCount() const { 188 return mCount; 189 } 190 191 typedef LightRefBase<T> basetype; 192 193 protected: 194 inline ~LightRefBase() { } 195 196 private: 197 friend class ReferenceMover; 198 inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } 199 inline static void renameRefId(T* ref, 200 const void* old_id, const void* new_id) { } 201 202 private: 203 mutable volatile int32_t mCount; 204 }; 205 206 // --------------------------------------------------------------------------- 207 208 template <typename T> 209 class wp 210 { 211 public: 212 typedef typename RefBase::weakref_type weakref_type; 213 214 inline wp() : m_ptr(0) { } 215 216 wp(T* other); 217 wp(const wp<T>& other); 218 wp(const sp<T>& other); 219 template<typename U> wp(U* other); 220 template<typename U> wp(const sp<U>& other); 221 template<typename U> wp(const wp<U>& other); 222 223 ~wp(); 224 225 // Assignment 226 227 wp& operator = (T* other); 228 wp& operator = (const wp<T>& other); 229 wp& operator = (const sp<T>& other); 230 231 template<typename U> wp& operator = (U* other); 232 template<typename U> wp& operator = (const wp<U>& other); 233 template<typename U> wp& operator = (const sp<U>& other); 234 235 void set_object_and_refs(T* other, weakref_type* refs); 236 237 // promotion to sp 238 239 sp<T> promote() const; 240 241 // Reset 242 243 void clear(); 244 245 // Accessors 246 247 inline weakref_type* get_refs() const { return m_refs; } 248 249 inline T* unsafe_get() const { return m_ptr; } 250 251 // Operators 252 253 COMPARE_WEAK(==) 254 COMPARE_WEAK(!=) 255 COMPARE_WEAK(>) 256 COMPARE_WEAK(<) 257 COMPARE_WEAK(<=) 258 COMPARE_WEAK(>=) 259 260 inline bool operator == (const wp<T>& o) const { 261 return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); 262 } 263 template<typename U> 264 inline bool operator == (const wp<U>& o) const { 265 return m_ptr == o.m_ptr; 266 } 267 268 inline bool operator > (const wp<T>& o) const { 269 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 270 } 271 template<typename U> 272 inline bool operator > (const wp<U>& o) const { 273 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 274 } 275 276 inline bool operator < (const wp<T>& o) const { 277 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 278 } 279 template<typename U> 280 inline bool operator < (const wp<U>& o) const { 281 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 282 } 283 inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } 284 template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } 285 inline bool operator <= (const wp<T>& o) const { return !operator > (o); } 286 template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } 287 inline bool operator >= (const wp<T>& o) const { return !operator < (o); } 288 template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } 289 290 private: 291 template<typename Y> friend class sp; 292 template<typename Y> friend class wp; 293 294 T* m_ptr; 295 weakref_type* m_refs; 296 }; 297 298 template <typename T> 299 TextOutput& operator<<(TextOutput& to, const wp<T>& val); 300 301 #undef COMPARE_WEAK 302 303 // --------------------------------------------------------------------------- 304 // No user serviceable parts below here. 305 306 template<typename T> 307 wp<T>::wp(T* other) 308 : m_ptr(other) 309 { 310 if (other) m_refs = other->createWeak(this); 311 } 312 313 template<typename T> 314 wp<T>::wp(const wp<T>& other) 315 : m_ptr(other.m_ptr), m_refs(other.m_refs) 316 { 317 if (m_ptr) m_refs->incWeak(this); 318 } 319 320 template<typename T> 321 wp<T>::wp(const sp<T>& other) 322 : m_ptr(other.m_ptr) 323 { 324 if (m_ptr) { 325 m_refs = m_ptr->createWeak(this); 326 } 327 } 328 329 template<typename T> template<typename U> 330 wp<T>::wp(U* other) 331 : m_ptr(other) 332 { 333 if (other) m_refs = other->createWeak(this); 334 } 335 336 template<typename T> template<typename U> 337 wp<T>::wp(const wp<U>& other) 338 : m_ptr(other.m_ptr) 339 { 340 if (m_ptr) { 341 m_refs = other.m_refs; 342 m_refs->incWeak(this); 343 } 344 } 345 346 template<typename T> template<typename U> 347 wp<T>::wp(const sp<U>& other) 348 : m_ptr(other.m_ptr) 349 { 350 if (m_ptr) { 351 m_refs = m_ptr->createWeak(this); 352 } 353 } 354 355 template<typename T> 356 wp<T>::~wp() 357 { 358 if (m_ptr) m_refs->decWeak(this); 359 } 360 361 template<typename T> 362 wp<T>& wp<T>::operator = (T* other) 363 { 364 weakref_type* newRefs = 365 other ? other->createWeak(this) : 0; 366 if (m_ptr) m_refs->decWeak(this); 367 m_ptr = other; 368 m_refs = newRefs; 369 return *this; 370 } 371 372 template<typename T> 373 wp<T>& wp<T>::operator = (const wp<T>& other) 374 { 375 weakref_type* otherRefs(other.m_refs); 376 T* otherPtr(other.m_ptr); 377 if (otherPtr) otherRefs->incWeak(this); 378 if (m_ptr) m_refs->decWeak(this); 379 m_ptr = otherPtr; 380 m_refs = otherRefs; 381 return *this; 382 } 383 384 template<typename T> 385 wp<T>& wp<T>::operator = (const sp<T>& other) 386 { 387 weakref_type* newRefs = 388 other != NULL ? other->createWeak(this) : 0; 389 T* otherPtr(other.m_ptr); 390 if (m_ptr) m_refs->decWeak(this); 391 m_ptr = otherPtr; 392 m_refs = newRefs; 393 return *this; 394 } 395 396 template<typename T> template<typename U> 397 wp<T>& wp<T>::operator = (U* other) 398 { 399 weakref_type* newRefs = 400 other ? other->createWeak(this) : 0; 401 if (m_ptr) m_refs->decWeak(this); 402 m_ptr = other; 403 m_refs = newRefs; 404 return *this; 405 } 406 407 template<typename T> template<typename U> 408 wp<T>& wp<T>::operator = (const wp<U>& other) 409 { 410 weakref_type* otherRefs(other.m_refs); 411 U* otherPtr(other.m_ptr); 412 if (otherPtr) otherRefs->incWeak(this); 413 if (m_ptr) m_refs->decWeak(this); 414 m_ptr = otherPtr; 415 m_refs = otherRefs; 416 return *this; 417 } 418 419 template<typename T> template<typename U> 420 wp<T>& wp<T>::operator = (const sp<U>& other) 421 { 422 weakref_type* newRefs = 423 other != NULL ? other->createWeak(this) : 0; 424 U* otherPtr(other.m_ptr); 425 if (m_ptr) m_refs->decWeak(this); 426 m_ptr = otherPtr; 427 m_refs = newRefs; 428 return *this; 429 } 430 431 template<typename T> 432 void wp<T>::set_object_and_refs(T* other, weakref_type* refs) 433 { 434 if (other) refs->incWeak(this); 435 if (m_ptr) m_refs->decWeak(this); 436 m_ptr = other; 437 m_refs = refs; 438 } 439 440 template<typename T> 441 sp<T> wp<T>::promote() const 442 { 443 sp<T> result; 444 if (m_ptr && m_refs->attemptIncStrong(&result)) { 445 result.set_pointer(m_ptr); 446 } 447 return result; 448 } 449 450 template<typename T> 451 void wp<T>::clear() 452 { 453 if (m_ptr) { 454 m_refs->decWeak(this); 455 m_ptr = 0; 456 } 457 } 458 459 template <typename T> 460 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) 461 { 462 return printWeakPointer(to, val.unsafe_get()); 463 } 464 465 // --------------------------------------------------------------------------- 466 467 // this class just serves as a namespace so TYPE::moveReferences can stay 468 // private. 469 class ReferenceMover { 470 public: 471 // it would be nice if we could make sure no extra code is generated 472 // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: 473 // Using a sp<RefBase> override doesn't work; it's a bit like we wanted 474 // a template<typename TYPE inherits RefBase> template... 475 476 template<typename TYPE> static inline 477 void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 478 479 class Renamer : public ReferenceRenamer { 480 sp<TYPE>* d; 481 sp<TYPE> const* s; 482 virtual void operator()(size_t i) const { 483 // The id are known to be the sp<>'s this pointer 484 TYPE::renameRefId(d[i].get(), &s[i], &d[i]); 485 } 486 public: 487 Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { } 488 }; 489 490 memmove(d, s, n*sizeof(sp<TYPE>)); 491 TYPE::renameRefs(n, Renamer(d, s)); 492 } 493 494 495 template<typename TYPE> static inline 496 void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 497 498 class Renamer : public ReferenceRenamer { 499 wp<TYPE>* d; 500 wp<TYPE> const* s; 501 virtual void operator()(size_t i) const { 502 // The id are known to be the wp<>'s this pointer 503 TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]); 504 } 505 public: 506 Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { } 507 }; 508 509 memmove(d, s, n*sizeof(wp<TYPE>)); 510 TYPE::renameRefs(n, Renamer(d, s)); 511 } 512 }; 513 514 // specialization for moving sp<> and wp<> types. 515 // these are used by the [Sorted|Keyed]Vector<> implementations 516 // sp<> and wp<> need to be handled specially, because they do not 517 // have trivial copy operation in the general case (see RefBase.cpp 518 // when DEBUG ops are enabled), but can be implemented very 519 // efficiently in most cases. 520 521 template<typename TYPE> inline 522 void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 523 ReferenceMover::move_references(d, s, n); 524 } 525 526 template<typename TYPE> inline 527 void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 528 ReferenceMover::move_references(d, s, n); 529 } 530 531 template<typename TYPE> inline 532 void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 533 ReferenceMover::move_references(d, s, n); 534 } 535 536 template<typename TYPE> inline 537 void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 538 ReferenceMover::move_references(d, s, n); 539 } 540 541 542 }; // namespace android 543 544 // --------------------------------------------------------------------------- 545 546 #endif // ANDROID_REF_BASE_H 547