~xnox/ubuntu/trusty/gcc-arm-linux-androideabi/dima

« back to all changes in this revision

Viewing changes to android/frameworks/native/include/utils/RefBase.h

  • Committer: Package Import Robot
  • Author(s): Dmitrijs Ledkovs
  • Date: 2013-07-05 10:12:24 UTC
  • Revision ID: package-import@ubuntu.com-20130705101224-6qo3e8jbz8p31aa1
Tags: upstream-0.20130705.1
ImportĀ upstreamĀ versionĀ 0.20130705.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
// ---------------------------------------------------------------------------
 
31
namespace android {
 
32
 
 
33
class TextOutput;
 
34
TextOutput& printWeakPointer(TextOutput& to, const void* val);
 
35
 
 
36
// ---------------------------------------------------------------------------
 
37
 
 
38
#define COMPARE_WEAK(_op_)                                      \
 
39
inline bool operator _op_ (const sp<T>& o) const {              \
 
40
    return m_ptr _op_ o.m_ptr;                                  \
 
41
}                                                               \
 
42
inline bool operator _op_ (const T* o) const {                  \
 
43
    return m_ptr _op_ o;                                        \
 
44
}                                                               \
 
45
template<typename U>                                            \
 
46
inline bool operator _op_ (const sp<U>& o) const {              \
 
47
    return m_ptr _op_ o.m_ptr;                                  \
 
48
}                                                               \
 
49
template<typename U>                                            \
 
50
inline bool operator _op_ (const U* o) const {                  \
 
51
    return m_ptr _op_ o;                                        \
 
52
}
 
53
 
 
54
// ---------------------------------------------------------------------------
 
55
class ReferenceMover;
 
56
class ReferenceConverterBase {
 
57
public:
 
58
    virtual size_t getReferenceTypeSize() const = 0;
 
59
    virtual void* getReferenceBase(void const*) const = 0;
 
60
    inline virtual ~ReferenceConverterBase() { }
 
61
};
 
62
 
 
63
// ---------------------------------------------------------------------------
 
64
 
 
65
class RefBase
 
66
{
 
67
public:
 
68
            void            incStrong(const void* id) const;
 
69
            void            decStrong(const void* id) const;
 
70
    
 
71
            void            forceIncStrong(const void* id) const;
 
72
 
 
73
            //! DEBUGGING ONLY: Get current strong ref count.
 
74
            int32_t         getStrongCount() const;
 
75
 
 
76
    class weakref_type
 
77
    {
 
78
    public:
 
79
        RefBase*            refBase() const;
 
80
        
 
81
        void                incWeak(const void* id);
 
82
        void                decWeak(const void* id);
 
83
        
 
84
        // acquires a strong reference if there is already one.
 
85
        bool                attemptIncStrong(const void* id);
 
86
        
 
87
        // acquires a weak reference if there is already one.
 
88
        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
 
89
        // for proper use.
 
90
        bool                attemptIncWeak(const void* id);
 
91
 
 
92
        //! DEBUGGING ONLY: Get current weak ref count.
 
93
        int32_t             getWeakCount() const;
 
94
 
 
95
        //! DEBUGGING ONLY: Print references held on object.
 
96
        void                printRefs() const;
 
97
 
 
98
        //! DEBUGGING ONLY: Enable tracking for this object.
 
99
        // enable -- enable/disable tracking
 
100
        // retain -- when tracking is enable, if true, then we save a stack trace
 
101
        //           for each reference and dereference; when retain == false, we
 
102
        //           match up references and dereferences and keep only the 
 
103
        //           outstanding ones.
 
104
        
 
105
        void                trackMe(bool enable, bool retain);
 
106
    };
 
107
    
 
108
            weakref_type*   createWeak(const void* id) const;
 
109
            
 
110
            weakref_type*   getWeakRefs() const;
 
111
 
 
112
            //! DEBUGGING ONLY: Print references held on object.
 
113
    inline  void            printRefs() const { getWeakRefs()->printRefs(); }
 
114
 
 
115
            //! DEBUGGING ONLY: Enable tracking of object.
 
116
    inline  void            trackMe(bool enable, bool retain)
 
117
    { 
 
118
        getWeakRefs()->trackMe(enable, retain); 
 
119
    }
 
120
 
 
121
    typedef RefBase basetype;
 
122
 
 
123
protected:
 
124
                            RefBase();
 
125
    virtual                 ~RefBase();
 
126
 
 
127
    //! Flags for extendObjectLifetime()
 
128
    enum {
 
129
        OBJECT_LIFETIME_STRONG  = 0x0000,
 
130
        OBJECT_LIFETIME_WEAK    = 0x0001,
 
131
        OBJECT_LIFETIME_MASK    = 0x0001
 
132
    };
 
133
    
 
134
            void            extendObjectLifetime(int32_t mode);
 
135
            
 
136
    //! Flags for onIncStrongAttempted()
 
137
    enum {
 
138
        FIRST_INC_STRONG = 0x0001
 
139
    };
 
140
    
 
141
    virtual void            onFirstRef();
 
142
    virtual void            onLastStrongRef(const void* id);
 
143
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
 
144
    virtual void            onLastWeakRef(const void* id);
 
145
 
 
146
private:
 
147
    friend class ReferenceMover;
 
148
    static void moveReferences(void* d, void const* s, size_t n,
 
149
            const ReferenceConverterBase& caster);
 
150
 
 
151
private:
 
152
    friend class weakref_type;
 
153
    class weakref_impl;
 
154
    
 
155
                            RefBase(const RefBase& o);
 
156
            RefBase&        operator=(const RefBase& o);
 
157
 
 
158
        weakref_impl* const mRefs;
 
159
};
 
160
 
 
161
// ---------------------------------------------------------------------------
 
162
 
 
163
template <class T>
 
164
class LightRefBase
 
165
{
 
166
public:
 
167
    inline LightRefBase() : mCount(0) { }
 
168
    inline void incStrong(const void* id) const {
 
169
        android_atomic_inc(&mCount);
 
170
    }
 
171
    inline void decStrong(const void* id) const {
 
172
        if (android_atomic_dec(&mCount) == 1) {
 
173
            delete static_cast<const T*>(this);
 
174
        }
 
175
    }
 
176
    //! DEBUGGING ONLY: Get current strong ref count.
 
177
    inline int32_t getStrongCount() const {
 
178
        return mCount;
 
179
    }
 
180
 
 
181
    typedef LightRefBase<T> basetype;
 
182
 
 
183
protected:
 
184
    inline ~LightRefBase() { }
 
185
 
 
186
private:
 
187
    friend class ReferenceMover;
 
188
    inline static void moveReferences(void* d, void const* s, size_t n,
 
189
            const ReferenceConverterBase& caster) { }
 
190
 
 
191
private:
 
192
    mutable volatile int32_t mCount;
 
193
};
 
194
 
 
195
// ---------------------------------------------------------------------------
 
196
 
 
197
template <typename T>
 
198
class wp
 
199
{
 
200
public:
 
201
    typedef typename RefBase::weakref_type weakref_type;
 
202
    
 
203
    inline wp() : m_ptr(0) { }
 
204
 
 
205
    wp(T* other);
 
206
    wp(const wp<T>& other);
 
207
    wp(const sp<T>& other);
 
208
    template<typename U> wp(U* other);
 
209
    template<typename U> wp(const sp<U>& other);
 
210
    template<typename U> wp(const wp<U>& other);
 
211
 
 
212
    ~wp();
 
213
    
 
214
    // Assignment
 
215
 
 
216
    wp& operator = (T* other);
 
217
    wp& operator = (const wp<T>& other);
 
218
    wp& operator = (const sp<T>& other);
 
219
    
 
220
    template<typename U> wp& operator = (U* other);
 
221
    template<typename U> wp& operator = (const wp<U>& other);
 
222
    template<typename U> wp& operator = (const sp<U>& other);
 
223
    
 
224
    void set_object_and_refs(T* other, weakref_type* refs);
 
225
 
 
226
    // promotion to sp
 
227
    
 
228
    sp<T> promote() const;
 
229
 
 
230
    // Reset
 
231
    
 
232
    void clear();
 
233
 
 
234
    // Accessors
 
235
    
 
236
    inline  weakref_type* get_refs() const { return m_refs; }
 
237
    
 
238
    inline  T* unsafe_get() const { return m_ptr; }
 
239
 
 
240
    // Operators
 
241
 
 
242
    COMPARE_WEAK(==)
 
243
    COMPARE_WEAK(!=)
 
244
    COMPARE_WEAK(>)
 
245
    COMPARE_WEAK(<)
 
246
    COMPARE_WEAK(<=)
 
247
    COMPARE_WEAK(>=)
 
248
 
 
249
    inline bool operator == (const wp<T>& o) const {
 
250
        return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
 
251
    }
 
252
    template<typename U>
 
253
    inline bool operator == (const wp<U>& o) const {
 
254
        return m_ptr == o.m_ptr;
 
255
    }
 
256
 
 
257
    inline bool operator > (const wp<T>& o) const {
 
258
        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
 
259
    }
 
260
    template<typename U>
 
261
    inline bool operator > (const wp<U>& o) const {
 
262
        return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
 
263
    }
 
264
 
 
265
    inline bool operator < (const wp<T>& o) const {
 
266
        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
 
267
    }
 
268
    template<typename U>
 
269
    inline bool operator < (const wp<U>& o) const {
 
270
        return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
 
271
    }
 
272
                         inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
 
273
    template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
 
274
                         inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
 
275
    template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
 
276
                         inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
 
277
    template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
 
278
 
 
279
private:
 
280
    template<typename Y> friend class sp;
 
281
    template<typename Y> friend class wp;
 
282
 
 
283
    T*              m_ptr;
 
284
    weakref_type*   m_refs;
 
285
};
 
286
 
 
287
template <typename T>
 
288
TextOutput& operator<<(TextOutput& to, const wp<T>& val);
 
289
 
 
290
#undef COMPARE_WEAK
 
291
 
 
292
// ---------------------------------------------------------------------------
 
293
// No user serviceable parts below here.
 
294
 
 
295
template<typename T>
 
296
wp<T>::wp(T* other)
 
297
    : m_ptr(other)
 
298
{
 
299
    if (other) m_refs = other->createWeak(this);
 
300
}
 
301
 
 
302
template<typename T>
 
303
wp<T>::wp(const wp<T>& other)
 
304
    : m_ptr(other.m_ptr), m_refs(other.m_refs)
 
305
{
 
306
    if (m_ptr) m_refs->incWeak(this);
 
307
}
 
308
 
 
309
template<typename T>
 
310
wp<T>::wp(const sp<T>& other)
 
311
    : m_ptr(other.m_ptr)
 
312
{
 
313
    if (m_ptr) {
 
314
        m_refs = m_ptr->createWeak(this);
 
315
    }
 
316
}
 
317
 
 
318
template<typename T> template<typename U>
 
319
wp<T>::wp(U* other)
 
320
    : m_ptr(other)
 
321
{
 
322
    if (other) m_refs = other->createWeak(this);
 
323
}
 
324
 
 
325
template<typename T> template<typename U>
 
326
wp<T>::wp(const wp<U>& other)
 
327
    : m_ptr(other.m_ptr)
 
328
{
 
329
    if (m_ptr) {
 
330
        m_refs = other.m_refs;
 
331
        m_refs->incWeak(this);
 
332
    }
 
333
}
 
334
 
 
335
template<typename T> template<typename U>
 
336
wp<T>::wp(const sp<U>& other)
 
337
    : m_ptr(other.m_ptr)
 
338
{
 
339
    if (m_ptr) {
 
340
        m_refs = m_ptr->createWeak(this);
 
341
    }
 
342
}
 
343
 
 
344
template<typename T>
 
345
wp<T>::~wp()
 
346
{
 
347
    if (m_ptr) m_refs->decWeak(this);
 
348
}
 
349
 
 
350
template<typename T>
 
351
wp<T>& wp<T>::operator = (T* other)
 
352
{
 
353
    weakref_type* newRefs =
 
354
        other ? other->createWeak(this) : 0;
 
355
    if (m_ptr) m_refs->decWeak(this);
 
356
    m_ptr = other;
 
357
    m_refs = newRefs;
 
358
    return *this;
 
359
}
 
360
 
 
361
template<typename T>
 
362
wp<T>& wp<T>::operator = (const wp<T>& other)
 
363
{
 
364
    weakref_type* otherRefs(other.m_refs);
 
365
    T* otherPtr(other.m_ptr);
 
366
    if (otherPtr) otherRefs->incWeak(this);
 
367
    if (m_ptr) m_refs->decWeak(this);
 
368
    m_ptr = otherPtr;
 
369
    m_refs = otherRefs;
 
370
    return *this;
 
371
}
 
372
 
 
373
template<typename T>
 
374
wp<T>& wp<T>::operator = (const sp<T>& other)
 
375
{
 
376
    weakref_type* newRefs =
 
377
        other != NULL ? other->createWeak(this) : 0;
 
378
    T* otherPtr(other.m_ptr);
 
379
    if (m_ptr) m_refs->decWeak(this);
 
380
    m_ptr = otherPtr;
 
381
    m_refs = newRefs;
 
382
    return *this;
 
383
}
 
384
 
 
385
template<typename T> template<typename U>
 
386
wp<T>& wp<T>::operator = (U* other)
 
387
{
 
388
    weakref_type* newRefs =
 
389
        other ? other->createWeak(this) : 0;
 
390
    if (m_ptr) m_refs->decWeak(this);
 
391
    m_ptr = other;
 
392
    m_refs = newRefs;
 
393
    return *this;
 
394
}
 
395
 
 
396
template<typename T> template<typename U>
 
397
wp<T>& wp<T>::operator = (const wp<U>& other)
 
398
{
 
399
    weakref_type* otherRefs(other.m_refs);
 
400
    U* otherPtr(other.m_ptr);
 
401
    if (otherPtr) otherRefs->incWeak(this);
 
402
    if (m_ptr) m_refs->decWeak(this);
 
403
    m_ptr = otherPtr;
 
404
    m_refs = otherRefs;
 
405
    return *this;
 
406
}
 
407
 
 
408
template<typename T> template<typename U>
 
409
wp<T>& wp<T>::operator = (const sp<U>& other)
 
410
{
 
411
    weakref_type* newRefs =
 
412
        other != NULL ? other->createWeak(this) : 0;
 
413
    U* otherPtr(other.m_ptr);
 
414
    if (m_ptr) m_refs->decWeak(this);
 
415
    m_ptr = otherPtr;
 
416
    m_refs = newRefs;
 
417
    return *this;
 
418
}
 
419
 
 
420
template<typename T>
 
421
void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
 
422
{
 
423
    if (other) refs->incWeak(this);
 
424
    if (m_ptr) m_refs->decWeak(this);
 
425
    m_ptr = other;
 
426
    m_refs = refs;
 
427
}
 
428
 
 
429
template<typename T>
 
430
sp<T> wp<T>::promote() const
 
431
{
 
432
    sp<T> result;
 
433
    if (m_ptr && m_refs->attemptIncStrong(&result)) {
 
434
        result.set_pointer(m_ptr);
 
435
    }
 
436
    return result;
 
437
}
 
438
 
 
439
template<typename T>
 
440
void wp<T>::clear()
 
441
{
 
442
    if (m_ptr) {
 
443
        m_refs->decWeak(this);
 
444
        m_ptr = 0;
 
445
    }
 
446
}
 
447
 
 
448
template <typename T>
 
449
inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
 
450
{
 
451
    return printWeakPointer(to, val.unsafe_get());
 
452
}
 
453
 
 
454
// ---------------------------------------------------------------------------
 
455
 
 
456
// this class just serves as a namespace so TYPE::moveReferences can stay
 
457
// private.
 
458
 
 
459
class ReferenceMover {
 
460
    // StrongReferenceCast and WeakReferenceCast do the impedance matching
 
461
    // between the generic (void*) implementation in Refbase and the strongly typed
 
462
    // template specializations below.
 
463
 
 
464
    template <typename TYPE>
 
465
    struct StrongReferenceCast : public ReferenceConverterBase {
 
466
        virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
 
467
        virtual void* getReferenceBase(void const* p) const {
 
468
            sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
 
469
            return static_cast<typename TYPE::basetype *>(sptr->get());
 
470
        }
 
471
    };
 
472
 
 
473
    template <typename TYPE>
 
474
    struct WeakReferenceCast : public ReferenceConverterBase {
 
475
        virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
 
476
        virtual void* getReferenceBase(void const* p) const {
 
477
            wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
 
478
            return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
 
479
        }
 
480
    };
 
481
 
 
482
public:
 
483
    template<typename TYPE> static inline
 
484
    void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
 
485
        memmove(d, s, n*sizeof(sp<TYPE>));
 
486
        StrongReferenceCast<TYPE> caster;
 
487
        TYPE::moveReferences(d, s, n, caster);
 
488
    }
 
489
    template<typename TYPE> static inline
 
490
    void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
 
491
        memmove(d, s, n*sizeof(wp<TYPE>));
 
492
        WeakReferenceCast<TYPE> caster;
 
493
        TYPE::moveReferences(d, s, n, caster);
 
494
    }
 
495
};
 
496
 
 
497
// specialization for moving sp<> and wp<> types.
 
498
// these are used by the [Sorted|Keyed]Vector<> implementations
 
499
// sp<> and wp<> need to be handled specially, because they do not
 
500
// have trivial copy operation in the general case (see RefBase.cpp
 
501
// when DEBUG ops are enabled), but can be implemented very
 
502
// efficiently in most cases.
 
503
 
 
504
template<typename TYPE> inline
 
505
void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
 
506
    ReferenceMover::move_references(d, s, n);
 
507
}
 
508
 
 
509
template<typename TYPE> inline
 
510
void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
 
511
    ReferenceMover::move_references(d, s, n);
 
512
}
 
513
 
 
514
template<typename TYPE> inline
 
515
void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
 
516
    ReferenceMover::move_references(d, s, n);
 
517
}
 
518
 
 
519
template<typename TYPE> inline
 
520
void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
 
521
    ReferenceMover::move_references(d, s, n);
 
522
}
 
523
 
 
524
 
 
525
}; // namespace android
 
526
 
 
527
// ---------------------------------------------------------------------------
 
528
 
 
529
#endif // ANDROID_REF_BASE_H