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