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