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