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 // This is a wrapper around LightRefBase that simply enforces a virtual 207 // destructor to eliminate the template requirement of LightRefBase 208 class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { 209 public: 210 virtual ~VirtualLightRefBase() {} 211 }; 212 213 // --------------------------------------------------------------------------- 214 215 template <typename T> 216 class wp 217 { 218 public: 219 typedef typename RefBase::weakref_type weakref_type; 220 221 inline wp() : m_ptr(0) { } 222 223 wp(T* other); 224 wp(const wp<T>& other); 225 wp(const sp<T>& other); 226 template<typename U> wp(U* other); 227 template<typename U> wp(const sp<U>& other); 228 template<typename U> wp(const wp<U>& other); 229 230 ~wp(); 231 232 // Assignment 233 234 wp& operator = (T* other); 235 wp& operator = (const wp<T>& other); 236 wp& operator = (const sp<T>& other); 237 238 template<typename U> wp& operator = (U* other); 239 template<typename U> wp& operator = (const wp<U>& other); 240 template<typename U> wp& operator = (const sp<U>& other); 241 242 void set_object_and_refs(T* other, weakref_type* refs); 243 244 // promotion to sp 245 246 sp<T> promote() const; 247 248 // Reset 249 250 void clear(); 251 252 // Accessors 253 254 inline weakref_type* get_refs() const { return m_refs; } 255 256 inline T* unsafe_get() const { return m_ptr; } 257 258 // Operators 259 260 COMPARE_WEAK(==) 261 COMPARE_WEAK(!=) 262 COMPARE_WEAK(>) 263 COMPARE_WEAK(<) 264 COMPARE_WEAK(<=) 265 COMPARE_WEAK(>=) 266 267 inline bool operator == (const wp<T>& o) const { 268 return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); 269 } 270 template<typename U> 271 inline bool operator == (const wp<U>& o) const { 272 return m_ptr == o.m_ptr; 273 } 274 275 inline bool operator > (const wp<T>& o) const { 276 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 277 } 278 template<typename U> 279 inline bool operator > (const wp<U>& o) const { 280 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 281 } 282 283 inline bool operator < (const wp<T>& o) const { 284 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 285 } 286 template<typename U> 287 inline bool operator < (const wp<U>& o) const { 288 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 289 } 290 inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } 291 template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } 292 inline bool operator <= (const wp<T>& o) const { return !operator > (o); } 293 template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } 294 inline bool operator >= (const wp<T>& o) const { return !operator < (o); } 295 template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } 296 297 private: 298 template<typename Y> friend class sp; 299 template<typename Y> friend class wp; 300 301 T* m_ptr; 302 weakref_type* m_refs; 303 }; 304 305 template <typename T> 306 TextOutput& operator<<(TextOutput& to, const wp<T>& val); 307 308 #undef COMPARE_WEAK 309 310 // --------------------------------------------------------------------------- 311 // No user serviceable parts below here. 312 313 template<typename T> 314 wp<T>::wp(T* other) 315 : m_ptr(other) 316 { 317 if (other) m_refs = other->createWeak(this); 318 } 319 320 template<typename T> 321 wp<T>::wp(const wp<T>& other) 322 : m_ptr(other.m_ptr), m_refs(other.m_refs) 323 { 324 if (m_ptr) m_refs->incWeak(this); 325 } 326 327 template<typename T> 328 wp<T>::wp(const sp<T>& other) 329 : m_ptr(other.m_ptr) 330 { 331 if (m_ptr) { 332 m_refs = m_ptr->createWeak(this); 333 } 334 } 335 336 template<typename T> template<typename U> 337 wp<T>::wp(U* other) 338 : m_ptr(other) 339 { 340 if (other) m_refs = other->createWeak(this); 341 } 342 343 template<typename T> template<typename U> 344 wp<T>::wp(const wp<U>& other) 345 : m_ptr(other.m_ptr) 346 { 347 if (m_ptr) { 348 m_refs = other.m_refs; 349 m_refs->incWeak(this); 350 } 351 } 352 353 template<typename T> template<typename U> 354 wp<T>::wp(const sp<U>& other) 355 : m_ptr(other.m_ptr) 356 { 357 if (m_ptr) { 358 m_refs = m_ptr->createWeak(this); 359 } 360 } 361 362 template<typename T> 363 wp<T>::~wp() 364 { 365 if (m_ptr) m_refs->decWeak(this); 366 } 367 368 template<typename T> 369 wp<T>& wp<T>::operator = (T* other) 370 { 371 weakref_type* newRefs = 372 other ? other->createWeak(this) : 0; 373 if (m_ptr) m_refs->decWeak(this); 374 m_ptr = other; 375 m_refs = newRefs; 376 return *this; 377 } 378 379 template<typename T> 380 wp<T>& wp<T>::operator = (const wp<T>& other) 381 { 382 weakref_type* otherRefs(other.m_refs); 383 T* otherPtr(other.m_ptr); 384 if (otherPtr) otherRefs->incWeak(this); 385 if (m_ptr) m_refs->decWeak(this); 386 m_ptr = otherPtr; 387 m_refs = otherRefs; 388 return *this; 389 } 390 391 template<typename T> 392 wp<T>& wp<T>::operator = (const sp<T>& other) 393 { 394 weakref_type* newRefs = 395 other != NULL ? other->createWeak(this) : 0; 396 T* otherPtr(other.m_ptr); 397 if (m_ptr) m_refs->decWeak(this); 398 m_ptr = otherPtr; 399 m_refs = newRefs; 400 return *this; 401 } 402 403 template<typename T> template<typename U> 404 wp<T>& wp<T>::operator = (U* other) 405 { 406 weakref_type* newRefs = 407 other ? other->createWeak(this) : 0; 408 if (m_ptr) m_refs->decWeak(this); 409 m_ptr = other; 410 m_refs = newRefs; 411 return *this; 412 } 413 414 template<typename T> template<typename U> 415 wp<T>& wp<T>::operator = (const wp<U>& other) 416 { 417 weakref_type* otherRefs(other.m_refs); 418 U* otherPtr(other.m_ptr); 419 if (otherPtr) otherRefs->incWeak(this); 420 if (m_ptr) m_refs->decWeak(this); 421 m_ptr = otherPtr; 422 m_refs = otherRefs; 423 return *this; 424 } 425 426 template<typename T> template<typename U> 427 wp<T>& wp<T>::operator = (const sp<U>& other) 428 { 429 weakref_type* newRefs = 430 other != NULL ? other->createWeak(this) : 0; 431 U* otherPtr(other.m_ptr); 432 if (m_ptr) m_refs->decWeak(this); 433 m_ptr = otherPtr; 434 m_refs = newRefs; 435 return *this; 436 } 437 438 template<typename T> 439 void wp<T>::set_object_and_refs(T* other, weakref_type* refs) 440 { 441 if (other) refs->incWeak(this); 442 if (m_ptr) m_refs->decWeak(this); 443 m_ptr = other; 444 m_refs = refs; 445 } 446 447 template<typename T> 448 sp<T> wp<T>::promote() const 449 { 450 sp<T> result; 451 if (m_ptr && m_refs->attemptIncStrong(&result)) { 452 result.set_pointer(m_ptr); 453 } 454 return result; 455 } 456 457 template<typename T> 458 void wp<T>::clear() 459 { 460 if (m_ptr) { 461 m_refs->decWeak(this); 462 m_ptr = 0; 463 } 464 } 465 466 template <typename T> 467 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) 468 { 469 return printWeakPointer(to, val.unsafe_get()); 470 } 471 472 // --------------------------------------------------------------------------- 473 474 // this class just serves as a namespace so TYPE::moveReferences can stay 475 // private. 476 class ReferenceMover { 477 public: 478 // it would be nice if we could make sure no extra code is generated 479 // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: 480 // Using a sp<RefBase> override doesn't work; it's a bit like we wanted 481 // a template<typename TYPE inherits RefBase> template... 482 483 template<typename TYPE> static inline 484 void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 485 486 class Renamer : public ReferenceRenamer { 487 sp<TYPE>* d; 488 sp<TYPE> const* s; 489 virtual void operator()(size_t i) const { 490 // The id are known to be the sp<>'s this pointer 491 TYPE::renameRefId(d[i].get(), &s[i], &d[i]); 492 } 493 public: 494 Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { } 495 }; 496 497 memmove(d, s, n*sizeof(sp<TYPE>)); 498 TYPE::renameRefs(n, Renamer(d, s)); 499 } 500 501 502 template<typename TYPE> static inline 503 void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 504 505 class Renamer : public ReferenceRenamer { 506 wp<TYPE>* d; 507 wp<TYPE> const* s; 508 virtual void operator()(size_t i) const { 509 // The id are known to be the wp<>'s this pointer 510 TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]); 511 } 512 public: 513 Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { } 514 }; 515 516 memmove(d, s, n*sizeof(wp<TYPE>)); 517 TYPE::renameRefs(n, Renamer(d, s)); 518 } 519 }; 520 521 // specialization for moving sp<> and wp<> types. 522 // these are used by the [Sorted|Keyed]Vector<> implementations 523 // sp<> and wp<> need to be handled specially, because they do not 524 // have trivial copy operation in the general case (see RefBase.cpp 525 // when DEBUG ops are enabled), but can be implemented very 526 // efficiently in most cases. 527 528 template<typename TYPE> inline 529 void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 530 ReferenceMover::move_references(d, s, n); 531 } 532 533 template<typename TYPE> inline 534 void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 535 ReferenceMover::move_references(d, s, n); 536 } 537 538 template<typename TYPE> inline 539 void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 540 ReferenceMover::move_references(d, s, n); 541 } 542 543 template<typename TYPE> inline 544 void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 545 ReferenceMover::move_references(d, s, n); 546 } 547 548 549 }; // namespace android 550 551 // --------------------------------------------------------------------------- 552 553 #endif // ANDROID_REF_BASE_H 554