(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
View Code

相关文章: