2
* Copyright (C) 2005 The Android Open Source Project
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
17
#ifndef ANDROID_REF_BASE_H
18
#define ANDROID_REF_BASE_H
20
#include <cutils/atomic.h>
23
#include <sys/types.h>
27
#include <utils/StrongPointer.h>
28
#include <utils/TypeHelpers.h>
30
// ---------------------------------------------------------------------------
34
TextOutput& printWeakPointer(TextOutput& to, const void* val);
36
// ---------------------------------------------------------------------------
38
#define COMPARE_WEAK(_op_) \
39
inline bool operator _op_ (const sp<T>& o) const { \
40
return m_ptr _op_ o.m_ptr; \
42
inline bool operator _op_ (const T* o) const { \
43
return m_ptr _op_ o; \
45
template<typename U> \
46
inline bool operator _op_ (const sp<U>& o) const { \
47
return m_ptr _op_ o.m_ptr; \
49
template<typename U> \
50
inline bool operator _op_ (const U* o) const { \
51
return m_ptr _op_ o; \
54
// ---------------------------------------------------------------------------
56
class ReferenceConverterBase {
58
virtual size_t getReferenceTypeSize() const = 0;
59
virtual void* getReferenceBase(void const*) const = 0;
60
inline virtual ~ReferenceConverterBase() { }
63
// ---------------------------------------------------------------------------
68
void incStrong(const void* id) const;
69
void decStrong(const void* id) const;
71
void forceIncStrong(const void* id) const;
73
//! DEBUGGING ONLY: Get current strong ref count.
74
int32_t getStrongCount() const;
79
RefBase* refBase() const;
81
void incWeak(const void* id);
82
void decWeak(const void* id);
84
// acquires a strong reference if there is already one.
85
bool attemptIncStrong(const void* id);
87
// acquires a weak reference if there is already one.
88
// This is not always safe. see ProcessState.cpp and BpBinder.cpp
90
bool attemptIncWeak(const void* id);
92
//! DEBUGGING ONLY: Get current weak ref count.
93
int32_t getWeakCount() const;
95
//! DEBUGGING ONLY: Print references held on object.
96
void printRefs() const;
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
105
void trackMe(bool enable, bool retain);
108
weakref_type* createWeak(const void* id) const;
110
weakref_type* getWeakRefs() const;
112
//! DEBUGGING ONLY: Print references held on object.
113
inline void printRefs() const { getWeakRefs()->printRefs(); }
115
//! DEBUGGING ONLY: Enable tracking of object.
116
inline void trackMe(bool enable, bool retain)
118
getWeakRefs()->trackMe(enable, retain);
121
typedef RefBase basetype;
127
//! Flags for extendObjectLifetime()
129
OBJECT_LIFETIME_STRONG = 0x0000,
130
OBJECT_LIFETIME_WEAK = 0x0001,
131
OBJECT_LIFETIME_MASK = 0x0001
134
void extendObjectLifetime(int32_t mode);
136
//! Flags for onIncStrongAttempted()
138
FIRST_INC_STRONG = 0x0001
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);
147
friend class ReferenceMover;
148
static void moveReferences(void* d, void const* s, size_t n,
149
const ReferenceConverterBase& caster);
152
friend class weakref_type;
155
RefBase(const RefBase& o);
156
RefBase& operator=(const RefBase& o);
158
weakref_impl* const mRefs;
161
// ---------------------------------------------------------------------------
167
inline LightRefBase() : mCount(0) { }
168
inline void incStrong(const void* id) const {
169
android_atomic_inc(&mCount);
171
inline void decStrong(const void* id) const {
172
if (android_atomic_dec(&mCount) == 1) {
173
delete static_cast<const T*>(this);
176
//! DEBUGGING ONLY: Get current strong ref count.
177
inline int32_t getStrongCount() const {
181
typedef LightRefBase<T> basetype;
184
inline ~LightRefBase() { }
187
friend class ReferenceMover;
188
inline static void moveReferences(void* d, void const* s, size_t n,
189
const ReferenceConverterBase& caster) { }
192
mutable volatile int32_t mCount;
195
// ---------------------------------------------------------------------------
197
template <typename T>
201
typedef typename RefBase::weakref_type weakref_type;
203
inline wp() : m_ptr(0) { }
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);
216
wp& operator = (T* other);
217
wp& operator = (const wp<T>& other);
218
wp& operator = (const sp<T>& other);
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);
224
void set_object_and_refs(T* other, weakref_type* refs);
228
sp<T> promote() const;
236
inline weakref_type* get_refs() const { return m_refs; }
238
inline T* unsafe_get() const { return m_ptr; }
249
inline bool operator == (const wp<T>& o) const {
250
return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
253
inline bool operator == (const wp<U>& o) const {
254
return m_ptr == o.m_ptr;
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);
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);
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);
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);
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); }
280
template<typename Y> friend class sp;
281
template<typename Y> friend class wp;
284
weakref_type* m_refs;
287
template <typename T>
288
TextOutput& operator<<(TextOutput& to, const wp<T>& val);
292
// ---------------------------------------------------------------------------
293
// No user serviceable parts below here.
299
if (other) m_refs = other->createWeak(this);
303
wp<T>::wp(const wp<T>& other)
304
: m_ptr(other.m_ptr), m_refs(other.m_refs)
306
if (m_ptr) m_refs->incWeak(this);
310
wp<T>::wp(const sp<T>& other)
314
m_refs = m_ptr->createWeak(this);
318
template<typename T> template<typename U>
322
if (other) m_refs = other->createWeak(this);
325
template<typename T> template<typename U>
326
wp<T>::wp(const wp<U>& other)
330
m_refs = other.m_refs;
331
m_refs->incWeak(this);
335
template<typename T> template<typename U>
336
wp<T>::wp(const sp<U>& other)
340
m_refs = m_ptr->createWeak(this);
347
if (m_ptr) m_refs->decWeak(this);
351
wp<T>& wp<T>::operator = (T* other)
353
weakref_type* newRefs =
354
other ? other->createWeak(this) : 0;
355
if (m_ptr) m_refs->decWeak(this);
362
wp<T>& wp<T>::operator = (const wp<T>& other)
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);
374
wp<T>& wp<T>::operator = (const sp<T>& other)
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);
385
template<typename T> template<typename U>
386
wp<T>& wp<T>::operator = (U* other)
388
weakref_type* newRefs =
389
other ? other->createWeak(this) : 0;
390
if (m_ptr) m_refs->decWeak(this);
396
template<typename T> template<typename U>
397
wp<T>& wp<T>::operator = (const wp<U>& other)
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);
408
template<typename T> template<typename U>
409
wp<T>& wp<T>::operator = (const sp<U>& other)
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);
421
void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
423
if (other) refs->incWeak(this);
424
if (m_ptr) m_refs->decWeak(this);
430
sp<T> wp<T>::promote() const
433
if (m_ptr && m_refs->attemptIncStrong(&result)) {
434
result.set_pointer(m_ptr);
443
m_refs->decWeak(this);
448
template <typename T>
449
inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
451
return printWeakPointer(to, val.unsafe_get());
454
// ---------------------------------------------------------------------------
456
// this class just serves as a namespace so TYPE::moveReferences can stay
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.
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());
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());
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);
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);
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.
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);
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);
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);
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);
525
}; // namespace android
527
// ---------------------------------------------------------------------------
529
#endif // ANDROID_REF_BASE_H