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