media/omx-plugin/include/froyo/utils/RefBase.h

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

mercurial