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