1/* 2 * Copyright (C) 2013 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 21#include <stdint.h> 22#include <sys/types.h> 23#include <stdlib.h> 24#include <string.h> 25 26#include "StrongPointer.h" 27#include "TypeHelpers.h" 28 29// --------------------------------------------------------------------------- 30namespace android { 31 32class TextOutput; 33TextOutput& printWeakPointer(TextOutput& to, const void* val); 34 35// --------------------------------------------------------------------------- 36 37#define COMPARE_WEAK(_op_) \ 38inline bool operator _op_ (const sp<T>& o) const { \ 39 return m_ptr _op_ o.m_ptr; \ 40} \ 41inline bool operator _op_ (const T* o) const { \ 42 return m_ptr _op_ o; \ 43} \ 44template<typename U> \ 45inline bool operator _op_ (const sp<U>& o) const { \ 46 return m_ptr _op_ o.m_ptr; \ 47} \ 48template<typename U> \ 49inline bool operator _op_ (const U* o) const { \ 50 return m_ptr _op_ o; \ 51} 52 53// --------------------------------------------------------------------------- 54class ReferenceMover; 55class ReferenceConverterBase { 56public: 57 virtual size_t getReferenceTypeSize() const = 0; 58 virtual void* getReferenceBase(void const*) const = 0; 59 inline virtual ~ReferenceConverterBase() { } 60}; 61 62// --------------------------------------------------------------------------- 63 64class RefBase 65{ 66public: 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 122protected: 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 145private: 146 friend class ReferenceMover; 147 static void moveReferences(void* d, void const* s, size_t n, 148 const ReferenceConverterBase& caster); 149 150private: 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 162template <class T> 163class LightRefBase 164{ 165public: 166 inline LightRefBase() : mCount(0) { } 167 inline void incStrong(__attribute__((unused)) const void* id) const { 168 __sync_fetch_and_add(&mCount, 1); 169 } 170 inline void decStrong(__attribute__((unused)) const void* id) const { 171 if (__sync_fetch_and_sub(&mCount, 1) == 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 182protected: 183 inline ~LightRefBase() { } 184 185private: 186 friend class ReferenceMover; 187 inline static void moveReferences(void* d, void const* s, size_t n, 188 const ReferenceConverterBase& caster) { } 189 190private: 191 mutable volatile int32_t mCount; 192}; 193 194// --------------------------------------------------------------------------- 195 196template <typename T> 197class wp 198{ 199public: 200 typedef typename RefBase::weakref_type weakref_type; 201 202 inline wp() : m_ptr(nullptr) { } 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 278private: 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 286template <typename T> 287TextOutput& operator<<(TextOutput& to, const wp<T>& val); 288 289#undef COMPARE_WEAK 290 291// --------------------------------------------------------------------------- 292// No user serviceable parts below here. 293 294template<typename T> 295wp<T>::wp(T* other) 296 : m_ptr(other) 297{ 298 if (other) m_refs = other->createWeak(this); 299} 300 301template<typename T> 302wp<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 308template<typename T> 309wp<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 317template<typename T> template<typename U> 318wp<T>::wp(U* other) 319 : m_ptr(other) 320{ 321 if (other) m_refs = other->createWeak(this); 322} 323 324template<typename T> template<typename U> 325wp<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 334template<typename T> template<typename U> 335wp<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 343template<typename T> 344wp<T>::~wp() 345{ 346 if (m_ptr) m_refs->decWeak(this); 347} 348 349template<typename T> 350wp<T>& wp<T>::operator = (T* other) 351{ 352 weakref_type* newRefs = 353 other ? other->createWeak(this) : nullptr; 354 if (m_ptr) m_refs->decWeak(this); 355 m_ptr = other; 356 m_refs = newRefs; 357 return *this; 358} 359 360template<typename T> 361wp<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 372template<typename T> 373wp<T>& wp<T>::operator = (const sp<T>& other) 374{ 375 weakref_type* newRefs = 376 other != nullptr ? other->createWeak(this) : nullptr; 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 384template<typename T> template<typename U> 385wp<T>& wp<T>::operator = (U* other) 386{ 387 weakref_type* newRefs = 388 other ? other->createWeak(this) : nullptr; 389 if (m_ptr) m_refs->decWeak(this); 390 m_ptr = other; 391 m_refs = newRefs; 392 return *this; 393} 394 395template<typename T> template<typename U> 396wp<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 407template<typename T> template<typename U> 408wp<T>& wp<T>::operator = (const sp<U>& other) 409{ 410 weakref_type* newRefs = 411 other != nullptr ? other->createWeak(this) : nullptr; 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 419template<typename T> 420void 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 428template<typename T> 429sp<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 438template<typename T> 439void wp<T>::clear() 440{ 441 if (m_ptr) { 442 m_refs->decWeak(this); 443 m_ptr = nullptr; 444 } 445} 446 447template <typename T> 448inline 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 458class 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 481public: 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 503template<typename TYPE> inline 504void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 505 ReferenceMover::move_references(d, s, n); 506} 507 508template<typename TYPE> inline 509void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { 510 ReferenceMover::move_references(d, s, n); 511} 512 513template<typename TYPE> inline 514void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { 515 ReferenceMover::move_references(d, s, n); 516} 517 518template<typename TYPE> inline 519void 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