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
21
#include <std/atomic.h>
24
#include <sys/types.h>
28
#include <std/StrongPointer.h>
29
#include <std/TypeHelpers.h>
31
// ---------------------------------------------------------------------------
34
// ---------------------------------------------------------------------------
36
#define COMPARE_WEAK(_op_) \
37
inline bool operator _op_ (const sp<T>& o) const { \
38
return m_ptr _op_ o.m_ptr; \
40
inline bool operator _op_ (const T* o) const { \
41
return m_ptr _op_ o; \
43
template<typename U> \
44
inline bool operator _op_ (const sp<U>& o) const { \
45
return m_ptr _op_ o.m_ptr; \
47
template<typename U> \
48
inline bool operator _op_ (const U* o) const { \
49
return m_ptr _op_ o; \
52
// ---------------------------------------------------------------------------
54
class ReferenceConverterBase {
56
virtual size_t getReferenceTypeSize() const = 0;
57
virtual void* getReferenceBase(void const*) const = 0;
58
inline virtual ~ReferenceConverterBase() { }
61
// ---------------------------------------------------------------------------
66
void incStrong(const void* id) const;
67
void decStrong(const void* id) const;
69
void forceIncStrong(const void* id) const;
71
//! DEBUGGING ONLY: Get current strong ref count.
72
int32_t getStrongCount() const;
77
RefBase* refBase() const;
79
void incWeak(const void* id);
80
void decWeak(const void* id);
82
// acquires a strong reference if there is already one.
83
bool attemptIncStrong(const void* id);
85
// acquires a weak reference if there is already one.
86
// This is not always safe. see ProcessState.cpp and BpBinder.cpp
88
bool attemptIncWeak(const void* id);
90
//! DEBUGGING ONLY: Get current weak ref count.
91
int32_t getWeakCount() const;
93
//! DEBUGGING ONLY: Print references held on object.
94
void printRefs() const;
96
//! DEBUGGING ONLY: Enable tracking for this object.
97
// enable -- enable/disable tracking
98
// retain -- when tracking is enable, if true, then we save a stack trace
99
// for each reference and dereference; when retain == false, we
100
// match up references and dereferences and keep only the
103
void trackMe(bool enable, bool retain);
106
weakref_type* createWeak(const void* id) const;
108
weakref_type* getWeakRefs() const;
110
//! DEBUGGING ONLY: Print references held on object.
111
inline void printRefs() const { getWeakRefs()->printRefs(); }
113
//! DEBUGGING ONLY: Enable tracking of object.
114
inline void trackMe(bool enable, bool retain)
116
getWeakRefs()->trackMe(enable, retain);
119
typedef RefBase basetype;
125
//! Flags for extendObjectLifetime()
127
OBJECT_LIFETIME_STRONG = 0x0000,
128
OBJECT_LIFETIME_WEAK = 0x0001,
129
OBJECT_LIFETIME_MASK = 0x0001
132
void extendObjectLifetime(int32_t mode);
134
//! Flags for onIncStrongAttempted()
136
FIRST_INC_STRONG = 0x0001
139
virtual void onFirstRef();
140
virtual void onLastStrongRef(const void* id);
141
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
142
virtual void onLastWeakRef(const void* id);
145
friend class ReferenceMover;
146
static void moveReferences(void* d, void const* s, size_t n,
147
const ReferenceConverterBase& caster);
150
friend class weakref_type;
153
RefBase(const RefBase& o);
154
RefBase& operator=(const RefBase& o);
156
weakref_impl* const mRefs;
159
// ---------------------------------------------------------------------------
161
template <typename T>
165
typedef typename RefBase::weakref_type weakref_type;
167
inline wp() : m_ptr(0) { }
170
wp(const wp<T>& other);
171
wp(const sp<T>& other);
172
template<typename U> wp(U* other);
173
template<typename U> wp(const sp<U>& other);
174
template<typename U> wp(const wp<U>& other);
180
wp& operator = (T* other);
181
wp& operator = (const wp<T>& other);
182
wp& operator = (const sp<T>& other);
184
template<typename U> wp& operator = (U* other);
185
template<typename U> wp& operator = (const wp<U>& other);
186
template<typename U> wp& operator = (const sp<U>& other);
188
void set_object_and_refs(T* other, weakref_type* refs);
192
sp<T> promote() const;
200
inline weakref_type* get_refs() const { return m_refs; }
202
inline T* unsafe_get() const { return m_ptr; }
213
inline bool operator == (const wp<T>& o) const {
214
return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
217
inline bool operator == (const wp<U>& o) const {
218
return m_ptr == o.m_ptr;
221
inline bool operator > (const wp<T>& o) const {
222
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
225
inline bool operator > (const wp<U>& o) const {
226
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
229
inline bool operator < (const wp<T>& o) const {
230
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
233
inline bool operator < (const wp<U>& o) const {
234
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
236
inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
237
template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
238
inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
239
template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
240
inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
241
template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
244
template<typename Y> friend class sp;
245
template<typename Y> friend class wp;
248
weakref_type* m_refs;
253
// ---------------------------------------------------------------------------
254
// No user serviceable parts below here.
260
if (other) m_refs = other->createWeak(this);
264
wp<T>::wp(const wp<T>& other)
265
: m_ptr(other.m_ptr), m_refs(other.m_refs)
267
if (m_ptr) m_refs->incWeak(this);
271
wp<T>::wp(const sp<T>& other)
275
m_refs = m_ptr->createWeak(this);
279
template<typename T> template<typename U>
283
if (other) m_refs = other->createWeak(this);
286
template<typename T> template<typename U>
287
wp<T>::wp(const wp<U>& other)
291
m_refs = other.m_refs;
292
m_refs->incWeak(this);
296
template<typename T> template<typename U>
297
wp<T>::wp(const sp<U>& other)
301
m_refs = m_ptr->createWeak(this);
308
if (m_ptr) m_refs->decWeak(this);
312
wp<T>& wp<T>::operator = (T* other)
314
weakref_type* newRefs =
315
other ? other->createWeak(this) : 0;
316
if (m_ptr) m_refs->decWeak(this);
323
wp<T>& wp<T>::operator = (const wp<T>& other)
325
weakref_type* otherRefs(other.m_refs);
326
T* otherPtr(other.m_ptr);
327
if (otherPtr) otherRefs->incWeak(this);
328
if (m_ptr) m_refs->decWeak(this);
335
wp<T>& wp<T>::operator = (const sp<T>& other)
337
weakref_type* newRefs =
338
other != NULL ? other->createWeak(this) : 0;
339
T* otherPtr(other.m_ptr);
340
if (m_ptr) m_refs->decWeak(this);
346
template<typename T> template<typename U>
347
wp<T>& wp<T>::operator = (U* other)
349
weakref_type* newRefs =
350
other ? other->createWeak(this) : 0;
351
if (m_ptr) m_refs->decWeak(this);
357
template<typename T> template<typename U>
358
wp<T>& wp<T>::operator = (const wp<U>& other)
360
weakref_type* otherRefs(other.m_refs);
361
U* otherPtr(other.m_ptr);
362
if (otherPtr) otherRefs->incWeak(this);
363
if (m_ptr) m_refs->decWeak(this);
369
template<typename T> template<typename U>
370
wp<T>& wp<T>::operator = (const sp<U>& other)
372
weakref_type* newRefs =
373
other != NULL ? other->createWeak(this) : 0;
374
U* otherPtr(other.m_ptr);
375
if (m_ptr) m_refs->decWeak(this);
382
void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
384
if (other) refs->incWeak(this);
385
if (m_ptr) m_refs->decWeak(this);
391
sp<T> wp<T>::promote() const
394
if (m_ptr && m_refs->attemptIncStrong(&result)) {
395
result.set_pointer(m_ptr);
404
m_refs->decWeak(this);
409
} // namespace android
411
// ---------------------------------------------------------------------------
413
#endif // ANDROID_REF_BASE_H