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