RefBase.h revision d83186c444809beaaf181b11c857bc2ab675428e
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// ---------------------------------------------------------------------------
31namespace android {
32
33class TextOutput;
34TextOutput& printWeakPointer(TextOutput& to, const void* val);
35
36// ---------------------------------------------------------------------------
37
38#define COMPARE_WEAK(_op_)                                      \
39inline bool operator _op_ (const sp<T>& o) const {              \
40    return m_ptr _op_ o.m_ptr;                                  \
41}                                                               \
42inline bool operator _op_ (const T* o) const {                  \
43    return m_ptr _op_ o;                                        \
44}                                                               \
45template<typename U>                                            \
46inline bool operator _op_ (const sp<U>& o) const {              \
47    return m_ptr _op_ o.m_ptr;                                  \
48}                                                               \
49template<typename U>                                            \
50inline bool operator _op_ (const U* o) const {                  \
51    return m_ptr _op_ o;                                        \
52}
53
54// ---------------------------------------------------------------------------
55
56class ReferenceRenamer {
57protected:
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() { }
63public:
64    virtual void operator()(size_t i) const = 0;
65};
66
67// ---------------------------------------------------------------------------
68
69class RefBase
70{
71public:
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
127protected:
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
150private:
151    friend class weakref_type;
152    class weakref_impl;
153
154                            RefBase(const RefBase& o);
155            RefBase&        operator=(const RefBase& o);
156
157private:
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
173template <class T>
174class LightRefBase
175{
176public:
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
193protected:
194    inline ~LightRefBase() { }
195
196private:
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
202private:
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
208class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> {
209public:
210    virtual ~VirtualLightRefBase() {}
211};
212
213// ---------------------------------------------------------------------------
214
215template <typename T>
216class wp
217{
218public:
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
297private:
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
305template <typename T>
306TextOutput& operator<<(TextOutput& to, const wp<T>& val);
307
308#undef COMPARE_WEAK
309
310// ---------------------------------------------------------------------------
311// No user serviceable parts below here.
312
313template<typename T>
314wp<T>::wp(T* other)
315    : m_ptr(other)
316{
317    if (other) m_refs = other->createWeak(this);
318}
319
320template<typename T>
321wp<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
327template<typename T>
328wp<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
336template<typename T> template<typename U>
337wp<T>::wp(U* other)
338    : m_ptr(other)
339{
340    if (other) m_refs = other->createWeak(this);
341}
342
343template<typename T> template<typename U>
344wp<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
353template<typename T> template<typename U>
354wp<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
362template<typename T>
363wp<T>::~wp()
364{
365    if (m_ptr) m_refs->decWeak(this);
366}
367
368template<typename T>
369wp<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
379template<typename T>
380wp<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
391template<typename T>
392wp<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
403template<typename T> template<typename U>
404wp<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
414template<typename T> template<typename U>
415wp<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
426template<typename T> template<typename U>
427wp<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
438template<typename T>
439void 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
447template<typename T>
448sp<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
457template<typename T>
458void wp<T>::clear()
459{
460    if (m_ptr) {
461        m_refs->decWeak(this);
462        m_ptr = 0;
463    }
464}
465
466template <typename T>
467inline 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.
476class ReferenceMover {
477public:
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
528template<typename TYPE> inline
529void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
530    ReferenceMover::move_references(d, s, n);
531}
532
533template<typename TYPE> inline
534void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
535    ReferenceMover::move_references(d, s, n);
536}
537
538template<typename TYPE> inline
539void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
540    ReferenceMover::move_references(d, s, n);
541}
542
543template<typename TYPE> inline
544void 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