(1)在Android中,RefBase结合了sp和wp,实现了一套通过引用计数的方法来控制对象声明周期的方法。
RefBase的定义在/frameworks/base/include/utils/RefBase.h,实现在/frameworks/base/libs/utils/RefBase.cpp。
wp的定义在/frameworks/base/include/utils/RefBase.h,
sp的定义在/frameworks/base/include/utils/StrongPointer.h中。
(2)weakref_impl是weakref_type 的子类
android_atomic_dec(&mCount) == 1 mCount减1,但是返回的是mCount减1之前的值。如果返回1,表示这次减过之后引用计数就是0了,就把对象delete掉。
android_atomic_inc(&impl->mStrong) mCount加1,但是返回的是mCount加1之前的值。
android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong); 加一个数,在此加的是(-INITIAL_STRONG_VALUE)
android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) 表示如果impl->mStrong的值为curCount,则把impl->mString的值改为curCount+1
(3)对象声明周期的控制
enum {
OBJECT_LIFETIME_STRONG = 0x0000,
OBJECT_LIFETIME_WEAK = 0x0001,
OBJECT_LIFETIME_MASK = 0x0001
};
void extendObjectLifetime(int32_t mode);
RefBase中,声明了一个枚举和extendObjectLifetime函数,来控制对象的生命周期。
void RefBase::extendObjectLifetime(int32_t mode)
{
android_atomic_or(mode, &mRefs->mFlags); // 用mode给weakref_impl的mFlags赋值 mFlags只在这一个地方赋值
}
(4)
incStrong中, 将强引用数与弱引用数同时 +1
decStrong中,将强引用数与弱引用数同时 -1
incWeak中,只有弱引用数 +1
decWeak中,只有弱引用数 -1
(5)
weakref_impl.mFlag == OBJECT_LIFETIME_STRONG时:
强引用计数来控制对象的生命周期,弱引用对象控制weakref_impl的生命周期。
强引用为0,对象被delete;弱引用为0时,weakref_impl被delete。
记住:使用wp时,要有sp生成,否则可能会引起segment fault。
weakref_impl.mFlag == OBJECT_LIFETIME_WEAK时:
由弱引用来控制对象和weakref_impl的生命周期。
强引用为0无作用,弱引用为0时,对象和weakref_impl被同时delete。
(6)
void RefBase::incStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->incWeak(id); refs->addStrongRef(id); //refs->mStrong的值+1,但是返回的c是+1之前的值 const int32_t c = android_atomic_inc(&refs->mStrong); ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); #if PRINT_REFS ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); #endif if (c != INITIAL_STRONG_VALUE) { //+1之前不是INITAL_STRONG_VALUE,返回 return; } //refs->mStrong= INITIAL_STRONG_VALUE + 1 - INITIAL_STRONG_VALUE = 1 最终为1 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); refs->mBase->onFirstRef(); }
第一次创建强引用会回调RefBase的onFirstRef()方法,这个方法很重要,派生类可以重载次方法,做一些初始化操作。在audio system中,很多类重载此方法!!!
RefBase.h 源文件
1 #ifndef ANDROID_REF_BASE_H 2 #define ANDROID_REF_BASE_H 3 4 #include <cutils/atomic.h> 5 6 #include <stdint.h> 7 #include <sys/types.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include <utils/StrongPointer.h> 12 #include <utils/TypeHelpers.h> 13 14 // --------------------------------------------------------------------------- 15 namespace android { 16 17 class TextOutput; 18 TextOutput& printWeakPointer(TextOutput& to, const void* val); 19 20 // --------------------------------------------------------------------------- 21 22 #define COMPARE_WEAK(_op_) 23 inline bool operator _op_ (const sp<T>& o) const { 24 return m_ptr _op_ o.m_ptr; 25 } 26 inline bool operator _op_ (const T* o) const { 27 return m_ptr _op_ o; 28 } 29 template<typename U> 30 inline bool operator _op_ (const sp<U>& o) const { 31 return m_ptr _op_ o.m_ptr; 32 } 33 template<typename U> 34 inline bool operator _op_ (const U* o) const { 35 return m_ptr _op_ o; 36 } 37 38 // --------------------------------------------------------------------------- 39 40 class ReferenceRenamer { 41 protected: 42 // destructor is purposedly not virtual so we avoid code overhead from 43 // subclasses; we have to make it protected to guarantee that it 44 // cannot be called from this base class (and to make strict compilers 45 // happy). 46 ~ReferenceRenamer() { } 47 public: 48 virtual void operator()(size_t i) const = 0; 49 }; 50 51 // --------------------------------------------------------------------------- 52 53 class RefBase 54 { 55 public: 56 void incStrong(const void* id) const; 57 void decStrong(const void* id) const; 58 59 void forceIncStrong(const void* id) const; 60 61 //! DEBUGGING ONLY: Get current strong ref count. 62 int32_t getStrongCount() const; 63 64 class weakref_type 65 { 66 public: 67 RefBase* refBase() const; 68 69 void incWeak(const void* id); 70 void decWeak(const void* id); 71 72 // acquires a strong reference if there is already one. 73 bool attemptIncStrong(const void* id); 74 75 // acquires a weak reference if there is already one. 76 // This is not always safe. see ProcessState.cpp and BpBinder.cpp 77 // for proper use. 78 bool attemptIncWeak(const void* id); 79 80 //! DEBUGGING ONLY: Get current weak ref count. 81 int32_t getWeakCount() const; 82 83 //! DEBUGGING ONLY: Print references held on object. 84 void printRefs() const; 85 86 //! DEBUGGING ONLY: Enable tracking for this object. 87 // enable -- enable/disable tracking 88 // retain -- when tracking is enable, if true, then we save a stack trace 89 // for each reference and dereference; when retain == false, we 90 // match up references and dereferences and keep only the 91 // outstanding ones. 92 93 void trackMe(bool enable, bool retain); 94 }; 95 96 weakref_type* createWeak(const void* id) const; 97 98 weakref_type* getWeakRefs() const; 99 100 //! DEBUGGING ONLY: Print references held on object. 101 inline void printRefs() const { getWeakRefs()->printRefs(); } 102 103 //! DEBUGGING ONLY: Enable tracking of object. 104 inline void trackMe(bool enable, bool retain) 105 { 106 getWeakRefs()->trackMe(enable, retain); 107 } 108 109 typedef RefBase basetype; 110 111 protected: 112 RefBase(); 113 virtual ~RefBase(); 114 115 //! Flags for extendObjectLifetime() 116 enum { 117 OBJECT_LIFETIME_STRONG = 0x0000, 118 OBJECT_LIFETIME_WEAK = 0x0001, 119 OBJECT_LIFETIME_MASK = 0x0001 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 private: 142 friend class ReferenceMover; 143 144 static void renameRefs(size_t n, const ReferenceRenamer& renamer); 145 146 static void renameRefId(weakref_type* ref, 147 const void* old_id, const void* new_id); 148 149 static void renameRefId(RefBase* ref, 150 const void* old_id, const void* new_id); 151 152 weakref_impl* const mRefs; 153 }; 154 155 // --------------------------------------------------------------------------- 156 157 template <class T> 158 class LightRefBase 159 { 160 public: 161 inline LightRefBase() : mCount(0) { } 162 inline void incStrong(__attribute__((unused)) const void* id) const { 163 android_atomic_inc(&mCount); 164 } 165 inline void decStrong(__attribute__((unused)) const void* id) const { 166 if (android_atomic_dec(&mCount) == 1) { 167 delete static_cast<const T*>(this); 168 } 169 } 170 //! DEBUGGING ONLY: Get current strong ref count. 171 inline int32_t getStrongCount() const { 172 return mCount; 173 } 174 175 typedef LightRefBase<T> basetype; 176 177 protected: 178 inline ~LightRefBase() { } 179 180 private: 181 friend class ReferenceMover; 182 inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } 183 inline static void renameRefId(T* ref, 184 const void* old_id, const void* new_id) { } 185 186 private: 187 mutable volatile int32_t mCount; 188 }; 189 190 // --------------------------------------------------------------------------- 191 192 template <typename T> 193 class wp 194 { 195 public: 196 typedef typename RefBase::weakref_type weakref_type; 197 198 inline wp() : m_ptr(0) { } 199 200 wp(T* other); 201 wp(const wp<T>& other); 202 wp(const sp<T>& other); 203 template<typename U> wp(U* other); 204 template<typename U> wp(const sp<U>& other); 205 template<typename U> wp(const wp<U>& other); 206 207 ~wp(); 208 209 // Assignment 210 211 wp& operator = (T* other); 212 wp& operator = (const wp<T>& other); 213 wp& operator = (const sp<T>& other); 214 215 template<typename U> wp& operator = (U* other); 216 template<typename U> wp& operator = (const wp<U>& other); 217 template<typename U> wp& operator = (const sp<U>& other); 218 219 void set_object_and_refs(T* other, weakref_type* refs); 220 221 // promotion to sp 222 223 sp<T> promote() const; 224 225 // Reset 226 227 void clear(); 228 229 // Accessors 230 231 inline weakref_type* get_refs() const { return m_refs; } 232 233 inline T* unsafe_get() const { return m_ptr; } 234 235 // Operators 236 237 COMPARE_WEAK(==) 238 COMPARE_WEAK(!=) 239 COMPARE_WEAK(>) 240 COMPARE_WEAK(<) 241 COMPARE_WEAK(<=) 242 COMPARE_WEAK(>=) 243 244 inline bool operator == (const wp<T>& o) const { 245 return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); 246 } 247 template<typename U> 248 inline bool operator == (const wp<U>& o) const { 249 return m_ptr == o.m_ptr; 250 } 251 252 inline bool operator > (const wp<T>& o) const { 253 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 254 } 255 template<typename U> 256 inline bool operator > (const wp<U>& o) const { 257 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 258 } 259 260 inline bool operator < (const wp<T>& o) const { 261 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 262 } 263 template<typename U> 264 inline bool operator < (const wp<U>& o) const { 265 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 266 } 267 inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } 268 template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } 269 inline bool operator <= (const wp<T>& o) const { return !operator > (o); } 270 template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } 271 inline bool operator >= (const wp<T>& o) const { return !operator < (o); } 272 template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } 273 274 private: 275 template<typename Y> friend class sp; 276 template<typename Y> friend class wp; 277 278 T* m_ptr; 279 weakref_type* m_refs; 280 }; 281 282 template <typename T> 283 TextOutput& operator<<(TextOutput& to, const wp<T>& val); 284 285 #undef COMPARE_WEAK 286 287 // --------------------------------------------------------------------------- 288 // No user serviceable parts below here. 289 290 template<typename T> 291 wp<T>::wp(T* other) 292 : m_ptr(other) 293 { 294 if (other) m_refs = other->createWeak(this); 295 } 296 297 template<typename T> 298 wp<T>::wp(const wp<T>& other) 299 : m_ptr(other.m_ptr), m_refs(other.m_refs) 300 { 301 if (m_ptr) m_refs->incWeak(this); 302 } 303 304 template<typename T> 305 wp<T>::wp(const sp<T>& other) 306 : m_ptr(other.m_ptr) 307 { 308 if (m_ptr) { 309 m_refs = m_ptr->createWeak(this); 310 } 311 } 312 313 template<typename T> template<typename U> 314 wp<T>::wp(U* other) 315 : m_ptr(other) 316 { 317 if (other) m_refs = other->createWeak(this); 318 } 319 320 template<typename T> template<typename U> 321 wp<T>::wp(const wp<U>& other) 322 : m_ptr(other.m_ptr) 323 { 324 if (m_ptr) { 325 m_refs = other.m_refs; 326 m_refs->incWeak(this); 327 } 328 } 329 330 template<typename T> template<typename U> 331 wp<T>::wp(const sp<U>& other) 332 : m_ptr(other.m_ptr) 333 { 334 if (m_ptr) { 335 m_refs = m_ptr->createWeak(this); 336 } 337 } 338 339 template<typename T> 340 wp<T>::~wp() 341 { 342 if (m_ptr) m_refs->decWeak(this); 343 } 344 345 template<typename T> 346 wp<T>& wp<T>::operator = (T* other) 347 { 348 weakref_type* newRefs = 349 other ? other->createWeak(this) : 0; 350 if (m_ptr) m_refs->decWeak(this); 351 m_ptr = other; 352 m_refs = newRefs; 353 return *this; 354 } 355 356 template<typename T> 357 wp<T>& wp<T>::operator = (const wp<T>& other) 358 { 359 weakref_type* otherRefs(other.m_refs); 360 T* otherPtr(other.m_ptr); 361 if (otherPtr) otherRefs->incWeak(this); 362 if (m_ptr) m_refs->decWeak(this); 363 m_ptr = otherPtr; 364 m_refs = otherRefs; 365 return *this; 366 } 367 368 template<typename T> 369 wp<T>& wp<T>::operator = (const sp<T>& other) 370 { 371 weakref_type* newRefs = 372 other != NULL ? other->createWeak(this) : 0; 373 T* otherPtr(other.m_ptr); 374 if (m_ptr) m_refs->decWeak(this); 375 m_ptr = otherPtr; 376 m_refs = newRefs; 377 return *this; 378 } 379 380 template<typename T> template<typename U> 381 wp<T>& wp<T>::operator = (U* other) 382 { 383 weakref_type* newRefs = 384 other ? other->createWeak(this) : 0; 385 if (m_ptr) m_refs->decWeak(this); 386 m_ptr = other; 387 m_refs = newRefs; 388 return *this; 389 } 390 391 template<typename T> template<typename U> 392 wp<T>& wp<T>::operator = (const wp<U>& other) 393 { 394 weakref_type* otherRefs(other.m_refs); 395 U* otherPtr(other.m_ptr); 396 if (otherPtr) otherRefs->incWeak(this); 397 if (m_ptr) m_refs->decWeak(this); 398 m_ptr = otherPtr; 399 m_refs = otherRefs; 400 return *this; 401 } 402 403 template<typename T> template<typename U> 404 wp<T>& wp<T>::operator = (const sp<U>& other) 405 { 406 weakref_type* newRefs = 407 other != NULL ? other->createWeak(this) : 0; 408 U* otherPtr(other.m_ptr); 409 if (m_ptr) m_refs->decWeak(this); 410 m_ptr = otherPtr; 411 m_refs = newRefs; 412 return *this; 413 } 414 415 template<typename T> 416 void wp<T>::set_object_and_refs(T* other, weakref_type* refs) 417 { 418 if (other) refs->incWeak(this); 419 if (m_ptr) m_refs->decWeak(this); 420 m_ptr = other; 421 m_refs = refs; 422 } 423 424 template<typename T> 425 sp<T> wp<T>::promote() const 426 { 427 sp<T> result; 428 if (m_ptr && m_refs->attemptIncStrong(&result)) { 429 result.set_pointer(m_ptr); 430 } 431 return result; 432 } 433 434 template<typename T> 435 void wp<T>::clear() 436 { 437 if (m_ptr) { 438 m_refs->decWeak(this); 439 m_ptr = 0; 440 } 441 } 442 443 template <typename T> 444 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) 445 { 446 return printWeakPointer(to, val.unsafe_get()); 447 } 448 449 // --------------------------------------------------------------------------- 450 451 // this class just serves as a namespace so TYPE::moveReferences can stay 452 // private. 453 class ReferenceMover { 454 public: 455 // it would be nice if we could make sure no extra code is generated 456 // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: 457 // Using a sp<RefBase> override doesn‘t work; it‘s a bit like we wanted 458 // a template<typename TYPE inherits RefBase> template... 459 460 template<typename TYPE> static inline 461 void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 462 463 class Renamer : public ReferenceRenamer { 464 sp<TYPE>* d; 465 sp<TYPE> const* s; 466 virtual void operator()(size_t i) const { 467 // The id are known to be the sp<>‘s this pointer 468 TYPE::renameRefId(d[i].get(), &s[i], &d[i]); 469 } 470 public: 471 Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { } 472 }; 473 474 memmove(d, s, n*sizeof(sp<TYPE>)); 475 TYPE::renameRefs(n, Renamer(d, s)); 476 } 477 478 479 template<typename TYPE> static inline 480 void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 481 482 class Renamer : public ReferenceRenamer { 483 wp<TYPE>* d; 484 wp<TYPE> const* s; 485 virtual void operator()(size_t i) const { 486 // The id are known to be the wp<>‘s this pointer 487 TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]); 488 } 489 public: 490 Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { } 491 }; 492 493 memmove(d, s, n*sizeof(wp<TYPE>)); 494 TYPE::renameRefs(n, Renamer(d, s)); 495 } 496 }; 497 498 // specialization for moving sp<> and wp<> types. 499 // these are used by the [Sorted|Keyed]Vector<> implementations 500 // sp<> and wp<> need to be handled specially, because they do not 501 // have trivial copy operation in the general case (see RefBase.cpp 502 // when DEBUG ops are enabled), but can be implemented very 503 // efficiently in most cases. 504 505 template<typename TYPE> inline 506 void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 507 ReferenceMover::move_references(d, s, n); 508 } 509 510 template<typename TYPE> inline 511 void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 512 ReferenceMover::move_references(d, s, n); 513 } 514 515 template<typename TYPE> inline 516 void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 517 ReferenceMover::move_references(d, s, n); 518 } 519 520 template<typename TYPE> inline 521 void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 522 ReferenceMover::move_references(d, s, n); 523 } 524 525 526 }; // namespace android 527 528 // --------------------------------------------------------------------------- 529 530 #endif // ANDROID_REF_BASE_H
去掉Debug和其他信息,简化之后的RefBase.h:
类RefBase:
1 class RefBase 2 { 3 public: 4 void incStrong(const void* id) const; 5 void decStrong(const void* id) const; 6 7 void forceIncStrong(const void* id) const; 8 9 //! DEBUGGING ONLY: Get current strong ref count. 10 int32_t getStrongCount() const; 11 12 weakref_type* createWeak(const void* id) const; 13 14 weakref_type* getWeakRefs() const; 15 16 typedef RefBase basetype; 17 18 protected: 19 RefBase(); 20 virtual ~RefBase(); 21 22 //! Flags for extendObjectLifetime() 23 enum { 24 OBJECT_LIFETIME_STRONG = 0x0000, 25 OBJECT_LIFETIME_WEAK = 0x0001, 26 OBJECT_LIFETIME_MASK = 0x0001 27 }; 28 29 void extendObjectLifetime(int32_t mode); 30 31 //! Flags for onIncStrongAttempted() 32 enum { 33 FIRST_INC_STRONG = 0x0001 34 }; 35 36 virtual void onFirstRef(); 37 virtual void onLastStrongRef(const void* id); 38 virtual bool onIncStrongAttempted(uint32_t flags, const void* id); 39 virtual void onLastWeakRef(const void* id); 40 41 private: 42 friend class weakref_type; 43 class weakref_impl; 44 45 RefBase(const RefBase& o); 46 RefBase& operator=(const RefBase& o); 47 48 };
类LightRefBase:
1 template <class T> 2 class LightRefBase 3 { 4 public: 5 inline LightRefBase() : mCount(0) { } 6 inline void incStrong(__attribute__((unused)) const void* id) const { 7 android_atomic_inc(&mCount); 8 } 9 inline void decStrong(__attribute__((unused)) const void* id) const { 10 if (android_atomic_dec(&mCount) == 1) { 11 delete static_cast<const T*>(this); 12 } 13 } 14 //! DEBUGGING ONLY: Get current strong ref count. 15 inline int32_t getStrongCount() const { 16 return mCount; 17 } 18 19 typedef LightRefBase<T> basetype; 20 21 protected: 22 inline ~LightRefBase() { } 23 24 private: 25 friend class ReferenceMover; 26 inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { } 27 inline static void renameRefId(T* ref, 28 const void* old_id, const void* new_id) { } 29 30 private: 31 mutable volatile int32_t mCount; 32 };
类wp:
1 template <typename T> 2 class wp 3 { 4 public: 5 typedef typename RefBase::weakref_type weakref_type; 6 7 inline wp() : m_ptr(0) { } 8 9 wp(T* other); 10 wp(const wp<T>& other); 11 wp(const sp<T>& other); 12 template<typename U> wp(U* other); 13 template<typename U> wp(const sp<U>& other); 14 template<typename U> wp(const wp<U>& other); 15 16 ~wp(); 17 18 // Assignment 19 20 wp& operator = (T* other); 21 wp& operator = (const wp<T>& other); 22 wp& operator = (const sp<T>& other); 23 24 template<typename U> wp& operator = (U* other); 25 template<typename U> wp& operator = (const wp<U>& other); 26 template<typename U> wp& operator = (const sp<U>& other); 27 28 void set_object_and_refs(T* other, weakref_type* refs); 29 30 // promotion to sp 31 32 sp<T> promote() const; 33 34 // Reset 35 36 void clear(); 37 38 // Accessors 39 40 inline weakref_type* get_refs() const { return m_refs; } 41 42 inline T* unsafe_get() const { return m_ptr; } 43 44 // Operators 45 46 COMPARE_WEAK(==) 47 COMPARE_WEAK(!=) 48 COMPARE_WEAK(>) 49 COMPARE_WEAK(<) 50 COMPARE_WEAK(<=) 51 COMPARE_WEAK(>=) 52 53 inline bool operator == (const wp<T>& o) const { 54 return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); 55 } 56 template<typename U> 57 inline bool operator == (const wp<U>& o) const { 58 return m_ptr == o.m_ptr; 59 } 60 61 inline bool operator > (const wp<T>& o) const { 62 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 63 } 64 template<typename U> 65 inline bool operator > (const wp<U>& o) const { 66 return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); 67 } 68 69 inline bool operator < (const wp<T>& o) const { 70 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 71 } 72 template<typename U> 73 inline bool operator < (const wp<U>& o) const { 74 return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); 75 } 76 inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } 77 template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } 78 inline bool operator <= (const wp<T>& o) const { return !operator > (o); } 79 template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } 80 inline bool operator >= (const wp<T>& o) const { return !operator < (o); } 81 template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } 82 83 private: 84 template<typename Y> friend class sp; 85 template<typename Y> friend class wp; 86 87 T* m_ptr; 88 weakref_type* m_refs; 89 };
类wp函数实现:
1 template<typename T> 2 wp<T>::wp(T* other) 3 : m_ptr(other) 4 { 5 if (other) m_refs = other->createWeak(this); 6 } 7 8 template<typename T> 9 wp<T>::wp(const wp<T>& other) 10 : m_ptr(other.m_ptr), m_refs(other.m_refs) 11 { 12 if (m_ptr) m_refs->incWeak(this); 13 } 14 15 template<typename T> 16 wp<T>::wp(const sp<T>& other) 17 : m_ptr(other.m_ptr) 18 { 19 if (m_ptr) { 20 m_refs = m_ptr->createWeak(this); 21 } 22 } 23 24 template<typename T> template<typename U> 25 wp<T>::wp(U* other) 26 : m_ptr(other) 27 { 28 if (other) m_refs = other->createWeak(this); 29 } 30 31 template<typename T> template<typename U> 32 wp<T>::wp(const wp<U>& other) 33 : m_ptr(other.m_ptr) 34 { 35 if (m_ptr) { 36 m_refs = other.m_refs; 37 m_refs->incWeak(this); 38 } 39 } 40 41 template<typename T> template<typename U> 42 wp<T>::wp(const sp<U>& other) 43 : m_ptr(other.m_ptr) 44 { 45 if (m_ptr) { 46 m_refs = m_ptr->createWeak(this); 47 } 48 } 49 50 template<typename T> 51 wp<T>::~wp() 52 { 53 if (m_ptr) m_refs->decWeak(this); 54 } 55 56 template<typename T> 57 wp<T>& wp<T>::operator = (T* other) 58 { 59 weakref_type* newRefs = 60 other ? other->createWeak(this) : 0; 61 if (m_ptr) m_refs->decWeak(this); 62 m_ptr = other; 63 m_refs = newRefs; 64 return *this; 65 } 66 67 template<typename T> 68 wp<T>& wp<T>::operator = (const wp<T>& other) 69 { 70 weakref_type* otherRefs(other.m_refs); 71 T* otherPtr(other.m_ptr); 72 if (otherPtr) otherRefs->incWeak(this); 73 if (m_ptr) m_refs->decWeak(this); 74 m_ptr = otherPtr; 75 m_refs = otherRefs; 76 return *this; 77 } 78 79 template<typename T> 80 wp<T>& wp<T>::operator = (const sp<T>& other) 81 { 82 weakref_type* newRefs = 83 other != NULL ? other->createWeak(this) : 0; 84 T* otherPtr(other.m_ptr); 85 if (m_ptr) m_refs->decWeak(this); 86 m_ptr = otherPtr; 87 m_refs = newRefs; 88 return *this; 89 } 90 91 template<typename T> template<typename U> 92 wp<T>& wp<T>::operator = (U* other) 93 { 94 weakref_type* newRefs = 95 other ? other->createWeak(this) : 0; 96 if (m_ptr) m_refs->decWeak(this); 97 m_ptr = other; 98 m_refs = newRefs; 99 return *this; 100 } 101 102 template<typename T> template<typename U> 103 wp<T>& wp<T>::operator = (const wp<U>& other) 104 { 105 weakref_type* otherRefs(other.m_refs); 106 U* otherPtr(other.m_ptr); 107 if (otherPtr) otherRefs->incWeak(this); 108 if (m_ptr) m_refs->decWeak(this); 109 m_ptr = otherPtr; 110 m_refs = otherRefs; 111 return *this; 112 } 113 114 template<typename T> template<typename U> 115 wp<T>& wp<T>::operator = (const sp<U>& other) 116 { 117 weakref_type* newRefs = 118 other != NULL ? other->createWeak(this) : 0; 119 U* otherPtr(other.m_ptr); 120 if (m_ptr) m_refs->decWeak(this); 121 m_ptr = otherPtr; 122 m_refs = newRefs; 123 return *this; 124 } 125 126 template<typename T> 127 void wp<T>::set_object_and_refs(T* other, weakref_type* refs) 128 { 129 if (other) refs->incWeak(this); 130 if (m_ptr) m_refs->decWeak(this); 131 m_ptr = other; 132 m_refs = refs; 133 } 134 135 template<typename T> 136 sp<T> wp<T>::promote() const 137 { 138 sp<T> result; 139 if (m_ptr && m_refs->attemptIncStrong(&result)) { 140 result.set_pointer(m_ptr); 141 } 142 return result; 143 } 144 145 template<typename T> 146 void wp<T>::clear() 147 { 148 if (m_ptr) { 149 m_refs->decWeak(this); 150 m_ptr = 0; 151 } 152 }
RefBase.cpp 源文件
简化之后的RefBase.cpp:
继承自weakref_type的类weakref_impl:
1 class RefBase::weakref_impl : public RefBase::weakref_type 2 { 3 public: 4 volatile int32_t mStrong; 5 volatile int32_t mWeak; 6 RefBase* const mBase; 7 volatile int32_t mFlags; 8 9 weakref_impl(RefBase* base) 10 : mStrong(INITIAL_STRONG_VALUE) 11 , mWeak(0) 12 , mBase(base) 13 , mFlags(0) 14 { 15 } 16 17 void addStrongRef(const void* /*id*/) { } 18 void removeStrongRef(const void* /*id*/) { } 19 void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { } 20 void addWeakRef(const void* /*id*/) { } 21 void removeWeakRef(const void* /*id*/) { } 22 void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { } 23 void printRefs() const { } 24 void trackMe(bool, bool) { } 25 26 };
RefBase类的函数实现:
1 #define INITIAL_STRONG_VALUE (1<<28) 2 3 4 void RefBase::incStrong(const void* id) const 5 { 6 weakref_impl* const refs = mRefs; 7 refs->incWeak(id); 8 9 refs->addStrongRef(id); 10 const int32_t c = android_atomic_inc(&refs->mStrong); 11 ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); 12 #if PRINT_REFS 13 ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); 14 #endif 15 if (c != INITIAL_STRONG_VALUE) { 16 return; 17 } 18 19 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 20 refs->mBase->onFirstRef(); 21 } 22 23 void RefBase::decStrong(const void* id) const 24 { 25 weakref_impl* const refs = mRefs; 26 refs->removeStrongRef(id); 27 const int32_t c = android_atomic_dec(&refs->mStrong); 28 #if PRINT_REFS 29 ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); 30 #endif 31 ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); 32 if (c == 1) { 33 refs->mBase->onLastStrongRef(id); 34 if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { 35 delete this; 36 } 37 } 38 refs->decWeak(id); 39 } 40 41 void RefBase::forceIncStrong(const void* id) const 42 { 43 weakref_impl* const refs = mRefs; 44 refs->incWeak(id); 45 46 refs->addStrongRef(id); 47 const int32_t c = android_atomic_inc(&refs->mStrong); 48 ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", 49 refs); 50 #if PRINT_REFS 51 ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c); 52 #endif 53 54 switch (c) { 55 case INITIAL_STRONG_VALUE: 56 android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 57 // fall through... 58 case 0: 59 refs->mBase->onFirstRef(); 60 } 61 } 62 63 int32_t RefBase::getStrongCount() const 64 { 65 return mRefs->mStrong; 66 } 67 68 RefBase::weakref_type* RefBase::createWeak(const void* id) const 69 { 70 mRefs->incWeak(id); 71 return mRefs; 72 } 73 74 RefBase::weakref_type* RefBase::getWeakRefs() const 75 { 76 return mRefs; 77 } 78 79 RefBase::RefBase() 80 : mRefs(new weakref_impl(this)) 81 { 82 } 83 84 RefBase::~RefBase() 85 { 86 if (mRefs->mStrong == INITIAL_STRONG_VALUE) { 87 // we never acquired a strong (and/or weak) reference on this object. 88 delete mRefs; 89 } else { 90 // life-time of this object is extended to WEAK or FOREVER, in 91 // which case weakref_impl doesn‘t out-live the object and we 92 // can free it now. 93 if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { 94 // It‘s possible that the weak count is not 0 if the object 95 // re-acquired a weak reference in its destructor 96 if (mRefs->mWeak == 0) { 97 delete mRefs; 98 } 99 } 100 } 101 // for debugging purposes, clear this. 102 const_cast<weakref_impl*&>(mRefs) = NULL; 103 } 104 105 void RefBase::extendObjectLifetime(int32_t mode) 106 { 107 android_atomic_or(mode, &mRefs->mFlags); 108 } 109 110 void RefBase::onFirstRef() 111 { 112 } 113 114 void RefBase::onLastStrongRef(const void* /*id*/) 115 { 116 } 117 118 bool RefBase::onIncStrongAttempted(uint32_t flags, const void* id) 119 { 120 return (flags&FIRST_INC_STRONG) ? true : false; 121 } 122 123 void RefBase::onLastWeakRef(const void* /*id*/) 124 { 125 }
RefBase::weakref_type 类的函数实现:
1 RefBase* RefBase::weakref_type::refBase() const 2 { 3 return static_cast<const weakref_impl*>(this)->mBase; 4 } 5 6 void RefBase::weakref_type::incWeak(const void* id) 7 { 8 weakref_impl* const impl = static_cast<weakref_impl*>(this); 9 impl->addWeakRef(id); 10 const int32_t c = android_atomic_inc(&impl->mWeak); 11 ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); 12 } 13 14 15 void RefBase::weakref_type::decWeak(const void* id) 16 { 17 weakref_impl* const impl = static_cast<weakref_impl*>(this); 18 impl->removeWeakRef(id); 19 const int32_t c = android_atomic_dec(&impl->mWeak); 20 ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); 21 if (c != 1) return; 22 23 if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { 24 // This is the regular lifetime case. The object is destroyed 25 // when the last strong reference goes away. Since weakref_impl 26 // outlive the object, it is not destroyed in the dtor, and 27 // we‘ll have to do it here. 28 if (impl->mStrong == INITIAL_STRONG_VALUE) { 29 // Special case: we never had a strong reference, so we need to 30 // destroy the object now. 31 delete impl->mBase; 32 } else { 33 // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); 34 delete impl; 35 } 36 } else { 37 // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER} 38 impl->mBase->onLastWeakRef(id); 39 if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { 40 // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference 41 // is gone, we can destroy the object. 42 delete impl->mBase; 43 } 44 } 45 } 46 47 bool RefBase::weakref_type::attemptIncStrong(const void* id) 48 { 49 incWeak(id); 50 51 weakref_impl* const impl = static_cast<weakref_impl*>(this); 52 int32_t curCount = impl->mStrong; 53 54 ALOG_ASSERT(curCount >= 0, 55 "attemptIncStrong called on %p after underflow", this); 56 57 while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { 58 // we‘re in the easy/common case of promoting a weak-reference 59 // from an existing strong reference. 60 if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { 61 break; 62 } 63 // the strong count has changed on us, we need to re-assert our 64 // situation. 65 curCount = impl->mStrong; 66 } 67 68 if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { 69 // we‘re now in the harder case of either: 70 // - there never was a strong reference on us 71 // - or, all strong references have been released 72 if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { 73 // this object has a "normal" life-time, i.e.: it gets destroyed 74 // when the last strong reference goes away 75 if (curCount <= 0) { 76 // the last strong-reference got released, the object cannot 77 // be revived. 78 decWeak(id); 79 return false; 80 } 81 82 // here, curCount == INITIAL_STRONG_VALUE, which means 83 // there never was a strong-reference, so we can try to 84 // promote this object; we need to do that atomically. 85 while (curCount > 0) { 86 if (android_atomic_cmpxchg(curCount, curCount + 1, 87 &impl->mStrong) == 0) { 88 break; 89 } 90 // the strong count has changed on us, we need to re-assert our 91 // situation (e.g.: another thread has inc/decStrong‘ed us) 92 curCount = impl->mStrong; 93 } 94 95 if (curCount <= 0) { 96 // promote() failed, some other thread destroyed us in the 97 // meantime (i.e.: strong count reached zero). 98 decWeak(id); 99 return false; 100 } 101 } else { 102 // this object has an "extended" life-time, i.e.: it can be 103 // revived from a weak-reference only. 104 // Ask the object‘s implementation if it agrees to be revived 105 if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) { 106 // it didn‘t so give-up. 107 decWeak(id); 108 return false; 109 } 110 // grab a strong-reference, which is always safe due to the 111 // extended life-time. 112 curCount = android_atomic_inc(&impl->mStrong); 113 } 114 115 // If the strong reference count has already been incremented by 116 // someone else, the implementor of onIncStrongAttempted() is holding 117 // an unneeded reference. So call onLastStrongRef() here to remove it. 118 // (No, this is not pretty.) Note that we MUST NOT do this if we 119 // are in fact acquiring the first reference. 120 if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) { 121 impl->mBase->onLastStrongRef(id); 122 } 123 } 124 125 impl->addStrongRef(id); 126 127 #if PRINT_REFS 128 ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount); 129 #endif 130 131 // now we need to fix-up the count if it was INITIAL_STRONG_VALUE 132 // this must be done safely, i.e.: handle the case where several threads 133 // were here in attemptIncStrong(). 134 curCount = impl->mStrong; 135 while (curCount >= INITIAL_STRONG_VALUE) { 136 ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE, 137 "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE", 138 this); 139 if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE, 140 &impl->mStrong) == 0) { 141 break; 142 } 143 // the strong-count changed on us, we need to re-assert the situation, 144 // for e.g.: it‘s possible the fix-up happened in another thread. 145 curCount = impl->mStrong; 146 } 147 148 return true; 149 } 150 151 bool RefBase::weakref_type::attemptIncWeak(const void* id) 152 { 153 weakref_impl* const impl = static_cast<weakref_impl*>(this); 154 155 int32_t curCount = impl->mWeak; 156 ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", 157 this); 158 while (curCount > 0) { 159 if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) { 160 break; 161 } 162 curCount = impl->mWeak; 163 } 164 165 if (curCount > 0) { 166 impl->addWeakRef(id); 167 } 168 169 return curCount > 0; 170 } 171 172 int32_t RefBase::weakref_type::getWeakCount() const 173 { 174 return static_cast<const weakref_impl*>(this)->mWeak; 175 } 176 177 void RefBase::weakref_type::printRefs() const 178 { 179 static_cast<const weakref_impl*>(this)->printRefs(); 180 } 181 182 void RefBase::weakref_type::trackMe(bool enable, bool retain) 183 { 184 static_cast<weakref_impl*>(this)->trackMe(enable, retain); 185 }
sp类声明 (StrongPointer.h)
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_STRONG_POINTER_H 18 #define ANDROID_STRONG_POINTER_H 19 20 #include <cutils/atomic.h> 21 22 #include <stdint.h> 23 #include <sys/types.h> 24 #include <stdlib.h> 25 26 // --------------------------------------------------------------------------- 27 namespace android { 28 29 template<typename T> class wp; 30 31 // --------------------------------------------------------------------------- 32 33 #define COMPARE(_op_) 34 inline bool operator _op_ (const sp<T>& o) const { 35 return m_ptr _op_ o.m_ptr; 36 } 37 inline bool operator _op_ (const T* o) const { 38 return m_ptr _op_ o; 39 } 40 template<typename U> 41 inline bool operator _op_ (const sp<U>& o) const { 42 return m_ptr _op_ o.m_ptr; 43 } 44 template<typename U> 45 inline bool operator _op_ (const U* o) const { 46 return m_ptr _op_ o; 47 } 48 inline bool operator _op_ (const wp<T>& o) const { 49 return m_ptr _op_ o.m_ptr; 50 } 51 template<typename U> 52 inline bool operator _op_ (const wp<U>& o) const { 53 return m_ptr _op_ o.m_ptr; 54 } 55 56 // --------------------------------------------------------------------------- 57 58 template<typename T> 59 class sp { 60 public: 61 inline sp() : m_ptr(0) { } 62 63 sp(T* other); 64 sp(const sp<T>& other); 65 template<typename U> sp(U* other); 66 template<typename U> sp(const sp<U>& other); 67 68 ~sp(); 69 70 // Assignment 71 72 sp& operator = (T* other); 73 sp& operator = (const sp<T>& other); 74 75 template<typename U> sp& operator = (const sp<U>& other); 76 template<typename U> sp& operator = (U* other); 77 78 //! Special optimization for use by ProcessState (and nobody else). 79 void force_set(T* other); 80 81 // Reset 82 83 void clear(); 84 85 // Accessors 86 87 inline T& operator* () const { return *m_ptr; } 88 inline T* operator-> () const { return m_ptr; } 89 inline T* get() const { return m_ptr; } 90 91 // Operators 92 93 COMPARE(==) 94 COMPARE(!=) 95 COMPARE(>) 96 COMPARE(<) 97 COMPARE(<=) 98 COMPARE(>=) 99 100 private: 101 template<typename Y> friend class sp; 102 template<typename Y> friend class wp; 103 void set_pointer(T* ptr); 104 T* m_ptr; 105 }; 106 107 #undef COMPARE 108 109 // --------------------------------------------------------------------------- 110 // No user serviceable parts below here. 111 112 template<typename T> 113 sp<T>::sp(T* other) 114 : m_ptr(other) { 115 if (other) 116 other->incStrong(this); 117 } 118 119 template<typename T> 120 sp<T>::sp(const sp<T>& other) 121 : m_ptr(other.m_ptr) { 122 if (m_ptr) 123 m_ptr->incStrong(this); 124 } 125 126 template<typename T> template<typename U> 127 sp<T>::sp(U* other) 128 : m_ptr(other) { 129 if (other) 130 ((T*) other)->incStrong(this); 131 } 132 133 template<typename T> template<typename U> 134 sp<T>::sp(const sp<U>& other) 135 : m_ptr(other.m_ptr) { 136 if (m_ptr) 137 m_ptr->incStrong(this); 138 } 139 140 template<typename T> 141 sp<T>::~sp() { 142 if (m_ptr) 143 m_ptr->decStrong(this); 144 } 145 146 template<typename T> 147 sp<T>& sp<T>::operator =(const sp<T>& other) { 148 T* otherPtr(other.m_ptr); 149 if (otherPtr) 150 otherPtr->incStrong(this); 151 if (m_ptr) 152 m_ptr->decStrong(this); 153 m_ptr = otherPtr; 154 return *this; 155 } 156 157 template<typename T> 158 sp<T>& sp<T>::operator =(T* other) { 159 if (other) 160 other->incStrong(this); 161 if (m_ptr) 162 m_ptr->decStrong(this); 163 m_ptr = other; 164 return *this; 165 } 166 167 template<typename T> template<typename U> 168 sp<T>& sp<T>::operator =(const sp<U>& other) { 169 T* otherPtr(other.m_ptr); 170 if (otherPtr) 171 otherPtr->incStrong(this); 172 if (m_ptr) 173 m_ptr->decStrong(this); 174 m_ptr = otherPtr; 175 return *this; 176 } 177 178 template<typename T> template<typename U> 179 sp<T>& sp<T>::operator =(U* other) { 180 if (other) 181 ((T*) other)->incStrong(this); 182 if (m_ptr) 183 m_ptr->decStrong(this); 184 m_ptr = other; 185 return *this; 186 } 187 188 template<typename T> 189 void sp<T>::force_set(T* other) { 190 other->forceIncStrong(this); 191 m_ptr = other; 192 } 193 194 template<typename T> 195 void sp<T>::clear() { 196 if (m_ptr) { 197 m_ptr->decStrong(this); 198 m_ptr = 0; 199 } 200 } 201 202 template<typename T> 203 void sp<T>::set_pointer(T* ptr) { 204 m_ptr = ptr; 205 } 206 207 }; // namespace android 208 209 // --------------------------------------------------------------------------- 210 211 #endif // ANDROID_STRONG_POINTER_H