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