| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 2 | * Copyright (C) 2016 The Android Open Source Project | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 |  | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 17 |  | 
|  | 18 | // SOME COMMENTS ABOUT USAGE: | 
|  | 19 |  | 
|  | 20 | // This provides primarily wp<> weak pointer types and RefBase, which work | 
|  | 21 | // together with sp<> from <StrongPointer.h>. | 
|  | 22 |  | 
|  | 23 | // sp<> (and wp<>) are a type of smart pointer that use a well defined protocol | 
|  | 24 | // to operate. As long as the object they are templated with implements that | 
|  | 25 | // protocol, these smart pointers work. In several places the platform | 
|  | 26 | // instantiates sp<> with non-RefBase objects; the two are not tied to each | 
|  | 27 | // other. | 
|  | 28 |  | 
|  | 29 | // RefBase is such an implementation and it supports strong pointers, weak | 
|  | 30 | // pointers and some magic features for the binder. | 
|  | 31 |  | 
|  | 32 | // So, when using RefBase objects, you have the ability to use strong and weak | 
|  | 33 | // pointers through sp<> and wp<>. | 
|  | 34 |  | 
|  | 35 | // Normally, when the last strong pointer goes away, the object is destroyed, | 
|  | 36 | // i.e. it's destructor is called. HOWEVER, parts of its associated memory is not | 
|  | 37 | // freed until the last weak pointer is released. | 
|  | 38 |  | 
|  | 39 | // Weak pointers are essentially "safe" pointers. They are always safe to | 
|  | 40 | // access through promote(). They may return nullptr if the object was | 
|  | 41 | // destroyed because it ran out of strong pointers. This makes them good candidates | 
|  | 42 | // for keys in a cache for instance. | 
|  | 43 |  | 
|  | 44 | // Weak pointers remain valid for comparison purposes even after the underlying | 
|  | 45 | // object has been destroyed. Even if object A is destroyed and its memory reused | 
|  | 46 | // for B, A remaining weak pointer to A will not compare equal to one to B. | 
|  | 47 | // This again makes them attractive for use as keys. | 
|  | 48 |  | 
|  | 49 | // How is this supposed / intended to be used? | 
|  | 50 |  | 
|  | 51 | // Our recommendation is to use strong references (sp<>) when there is an | 
|  | 52 | // ownership relation. e.g. when an object "owns" another one, use a strong | 
|  | 53 | // ref. And of course use strong refs as arguments of functions (it's extremely | 
|  | 54 | // rare that a function will take a wp<>). | 
|  | 55 |  | 
|  | 56 | // Typically a newly allocated object will immediately be used to initialize | 
|  | 57 | // a strong pointer, which may then be used to construct or assign to other | 
|  | 58 | // strong and weak pointers. | 
|  | 59 |  | 
|  | 60 | // Use weak references when there are no ownership relation. e.g. the keys in a | 
|  | 61 | // cache (you cannot use plain pointers because there is no safe way to acquire | 
|  | 62 | // a strong reference from a vanilla pointer). | 
|  | 63 |  | 
|  | 64 | // This implies that two objects should never (or very rarely) have sp<> on | 
|  | 65 | // each other, because they can't both own each other. | 
|  | 66 |  | 
|  | 67 |  | 
|  | 68 | // Caveats with reference counting | 
|  | 69 |  | 
|  | 70 | // Obviously, circular strong references are a big problem; this creates leaks | 
|  | 71 | // and it's hard to debug -- except it's in fact really easy because RefBase has | 
|  | 72 | // tons of debugging code for that. It can basically tell you exactly where the | 
|  | 73 | // leak is. | 
|  | 74 |  | 
|  | 75 | // Another problem has to do with destructors with side effects. You must | 
|  | 76 | // assume that the destructor of reference counted objects can be called AT ANY | 
|  | 77 | // TIME. For instance code as simple as this: | 
|  | 78 |  | 
|  | 79 | // void setStuff(const sp<Stuff>& stuff) { | 
|  | 80 | //   std::lock_guard<std::mutex> lock(mMutex); | 
|  | 81 | //   mStuff = stuff; | 
|  | 82 | // } | 
|  | 83 |  | 
|  | 84 | // is very dangerous. This code WILL deadlock one day or another. | 
|  | 85 |  | 
|  | 86 | // What isn't obvious is that ~Stuff() can be called as a result of the | 
|  | 87 | // assignment. And it gets called with the lock held. First of all, the lock is | 
|  | 88 | // protecting mStuff, not ~Stuff(). Secondly, if ~Stuff() uses its own internal | 
|  | 89 | // mutex, now you have mutex ordering issues.  Even worse, if ~Stuff() is | 
|  | 90 | // virtual, now you're calling into "user" code (potentially), by that, I mean, | 
|  | 91 | // code you didn't even write. | 
|  | 92 |  | 
|  | 93 | // A correct way to write this code is something like: | 
|  | 94 |  | 
|  | 95 | // void setStuff(const sp<Stuff>& stuff) { | 
|  | 96 | //   std::unique_lock<std::mutex> lock(mMutex); | 
|  | 97 | //   sp<Stuff> hold = mStuff; | 
|  | 98 | //   mStuff = stuff; | 
|  | 99 | //   lock.unlock(); | 
|  | 100 | // } | 
|  | 101 |  | 
|  | 102 | // More importantly, reference counted objects should do as little work as | 
|  | 103 | // possible in their destructor, or at least be mindful that their destructor | 
|  | 104 | // could be called from very weird and unintended places. | 
|  | 105 |  | 
|  | 106 | // Other more specific restrictions for wp<> and sp<>: | 
|  | 107 |  | 
| Hans Boehm | 23c857e | 2016-08-02 18:39:30 -0700 | [diff] [blame] | 108 | // Do not construct a strong pointer to "this" in an object's constructor. | 
|  | 109 | // The onFirstRef() callback would be made on an incompletely constructed | 
|  | 110 | // object. | 
|  | 111 | // Construction of a weak pointer to "this" in an object's constructor is also | 
|  | 112 | // discouraged. But the implementation was recently changed so that, in the | 
|  | 113 | // absence of extendObjectLifetime() calls, weak pointers no longer impact | 
|  | 114 | // object lifetime, and hence this no longer risks premature deallocation, | 
|  | 115 | // and hence usually works correctly. | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 116 |  | 
|  | 117 | // Such strong or weak pointers can be safely created in the RefBase onFirstRef() | 
|  | 118 | // callback. | 
|  | 119 |  | 
|  | 120 | // Use of wp::unsafe_get() for any purpose other than debugging is almost | 
|  | 121 | // always wrong.  Unless you somehow know that there is a longer-lived sp<> to | 
|  | 122 | // the same object, it may well return a pointer to a deallocated object that | 
|  | 123 | // has since been reallocated for a different purpose. (And if you know there | 
|  | 124 | // is a longer-lived sp<>, why not use an sp<> directly?) A wp<> should only be | 
|  | 125 | // dereferenced by using promote(). | 
|  | 126 |  | 
| Hans Boehm | 23c857e | 2016-08-02 18:39:30 -0700 | [diff] [blame] | 127 | // Any object inheriting from RefBase should always be destroyed as the result | 
|  | 128 | // of a reference count decrement, not via any other means.  Such objects | 
|  | 129 | // should never be stack allocated, or appear directly as data members in other | 
|  | 130 | // objects. Objects inheriting from RefBase should have their strong reference | 
|  | 131 | // count incremented as soon as possible after construction. Usually this | 
|  | 132 | // will be done via construction of an sp<> to the object, but may instead | 
|  | 133 | // involve other means of calling RefBase::incStrong(). | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 134 | // Explicitly deleting or otherwise destroying a RefBase object with outstanding | 
| Hans Boehm | 23c857e | 2016-08-02 18:39:30 -0700 | [diff] [blame] | 135 | // wp<> or sp<> pointers to it will result in an abort or heap corruption. | 
|  | 136 |  | 
|  | 137 | // It is particularly important not to mix sp<> and direct storage management | 
|  | 138 | // since the sp from raw pointer constructor is implicit. Thus if a RefBase- | 
|  | 139 | // -derived object of type T is managed without ever incrementing its strong | 
|  | 140 | // count, and accidentally passed to f(sp<T>), a strong pointer to the object | 
|  | 141 | // will be temporarily constructed and destroyed, prematurely deallocating the | 
|  | 142 | // object, and resulting in heap corruption. None of this would be easily | 
|  | 143 | // visible in the source. | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 144 |  | 
|  | 145 | // Extra Features: | 
|  | 146 |  | 
|  | 147 | // RefBase::extendObjectLifetime() can be used to prevent destruction of the | 
|  | 148 | // object while there are still weak references. This is really special purpose | 
|  | 149 | // functionality to support Binder. | 
|  | 150 |  | 
|  | 151 | // Wp::promote(), implemented via the attemptIncStrong() member function, is | 
|  | 152 | // used to try to convert a weak pointer back to a strong pointer.  It's the | 
|  | 153 | // normal way to try to access the fields of an object referenced only through | 
|  | 154 | // a wp<>.  Binder code also sometimes uses attemptIncStrong() directly. | 
|  | 155 |  | 
|  | 156 | // RefBase provides a number of additional callbacks for certain reference count | 
|  | 157 | // events, as well as some debugging facilities. | 
|  | 158 |  | 
|  | 159 | // Debugging support can be enabled by turning on DEBUG_REFS in RefBase.cpp. | 
| Hans Boehm | 23c857e | 2016-08-02 18:39:30 -0700 | [diff] [blame] | 160 | // Otherwise little checking is provided. | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 161 |  | 
|  | 162 | // Thread safety: | 
|  | 163 |  | 
|  | 164 | // Like std::shared_ptr, sp<> and wp<> allow concurrent accesses to DIFFERENT | 
|  | 165 | // sp<> and wp<> instances that happen to refer to the same underlying object. | 
|  | 166 | // They do NOT support concurrent access (where at least one access is a write) | 
|  | 167 | // to THE SAME sp<> or wp<>.  In effect, their thread-safety properties are | 
|  | 168 | // exactly like those of T*, NOT atomic<T*>. | 
|  | 169 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 170 | #ifndef ANDROID_REF_BASE_H | 
|  | 171 | #define ANDROID_REF_BASE_H | 
|  | 172 |  | 
| Hans Boehm | e263e6c | 2016-05-11 18:15:12 -0700 | [diff] [blame] | 173 | #include <atomic> | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 174 |  | 
|  | 175 | #include <stdint.h> | 
|  | 176 | #include <sys/types.h> | 
|  | 177 | #include <stdlib.h> | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 178 | #include <string.h> | 
|  | 179 |  | 
|  | 180 | #include <utils/StrongPointer.h> | 
| Jeff Brown | 9a0a76d | 2012-03-16 14:45:49 -0700 | [diff] [blame] | 181 | #include <utils/TypeHelpers.h> | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 182 |  | 
|  | 183 | // --------------------------------------------------------------------------- | 
|  | 184 | namespace android { | 
|  | 185 |  | 
| Mathias Agopian | 84a23fa | 2011-02-16 15:23:08 -0800 | [diff] [blame] | 186 | class TextOutput; | 
| Mathias Agopian | 84a23fa | 2011-02-16 15:23:08 -0800 | [diff] [blame] | 187 | TextOutput& printWeakPointer(TextOutput& to, const void* val); | 
|  | 188 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 189 | // --------------------------------------------------------------------------- | 
|  | 190 |  | 
| Mathias Agopian | ff49de7 | 2011-02-09 18:38:55 -0800 | [diff] [blame] | 191 | #define COMPARE_WEAK(_op_)                                      \ | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 192 | inline bool operator _op_ (const sp<T>& o) const {              \ | 
|  | 193 | return m_ptr _op_ o.m_ptr;                                  \ | 
|  | 194 | }                                                               \ | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 195 | inline bool operator _op_ (const T* o) const {                  \ | 
|  | 196 | return m_ptr _op_ o;                                        \ | 
|  | 197 | }                                                               \ | 
|  | 198 | template<typename U>                                            \ | 
|  | 199 | inline bool operator _op_ (const sp<U>& o) const {              \ | 
|  | 200 | return m_ptr _op_ o.m_ptr;                                  \ | 
|  | 201 | }                                                               \ | 
|  | 202 | template<typename U>                                            \ | 
| Mathias Agopian | ff49de7 | 2011-02-09 18:38:55 -0800 | [diff] [blame] | 203 | inline bool operator _op_ (const U* o) const {                  \ | 
|  | 204 | return m_ptr _op_ o;                                        \ | 
|  | 205 | } | 
|  | 206 |  | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 207 | // --------------------------------------------------------------------------- | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 208 |  | 
| Colin Cross | 1811d15 | 2016-09-26 14:24:48 -0700 | [diff] [blame] | 209 | // RefererenceRenamer is pure abstract, there is no virtual method | 
|  | 210 | // implementation to put in a translation unit in order to silence the | 
|  | 211 | // weak vtables warning. | 
|  | 212 | #if defined(__clang__) | 
|  | 213 | #pragma clang diagnostic push | 
|  | 214 | #pragma clang diagnostic ignored "-Wweak-vtables" | 
|  | 215 | #endif | 
|  | 216 |  | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 217 | class ReferenceRenamer { | 
|  | 218 | protected: | 
|  | 219 | // destructor is purposedly not virtual so we avoid code overhead from | 
|  | 220 | // subclasses; we have to make it protected to guarantee that it | 
|  | 221 | // cannot be called from this base class (and to make strict compilers | 
|  | 222 | // happy). | 
| Colin Cross | 1811d15 | 2016-09-26 14:24:48 -0700 | [diff] [blame] | 223 | ~ReferenceRenamer() { } | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 224 | public: | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 225 | virtual void operator()(size_t i) const = 0; | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 226 | }; | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 227 |  | 
| Colin Cross | 1811d15 | 2016-09-26 14:24:48 -0700 | [diff] [blame] | 228 | #if defined(__clang__) | 
|  | 229 | #pragma clang diagnostic pop | 
|  | 230 | #endif | 
|  | 231 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 232 | // --------------------------------------------------------------------------- | 
|  | 233 |  | 
|  | 234 | class RefBase | 
|  | 235 | { | 
|  | 236 | public: | 
|  | 237 | void            incStrong(const void* id) const; | 
|  | 238 | void            decStrong(const void* id) const; | 
|  | 239 |  | 
|  | 240 | void            forceIncStrong(const void* id) const; | 
|  | 241 |  | 
|  | 242 | //! DEBUGGING ONLY: Get current strong ref count. | 
|  | 243 | int32_t         getStrongCount() const; | 
|  | 244 |  | 
|  | 245 | class weakref_type | 
|  | 246 | { | 
|  | 247 | public: | 
|  | 248 | RefBase*            refBase() const; | 
|  | 249 |  | 
|  | 250 | void                incWeak(const void* id); | 
|  | 251 | void                decWeak(const void* id); | 
|  | 252 |  | 
| Mathias Agopian | ad09965 | 2011-08-10 21:07:02 -0700 | [diff] [blame] | 253 | // acquires a strong reference if there is already one. | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 254 | bool                attemptIncStrong(const void* id); | 
|  | 255 |  | 
| Mathias Agopian | ad09965 | 2011-08-10 21:07:02 -0700 | [diff] [blame] | 256 | // acquires a weak reference if there is already one. | 
|  | 257 | // This is not always safe. see ProcessState.cpp and BpBinder.cpp | 
|  | 258 | // for proper use. | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 259 | bool                attemptIncWeak(const void* id); | 
|  | 260 |  | 
|  | 261 | //! DEBUGGING ONLY: Get current weak ref count. | 
|  | 262 | int32_t             getWeakCount() const; | 
|  | 263 |  | 
|  | 264 | //! DEBUGGING ONLY: Print references held on object. | 
|  | 265 | void                printRefs() const; | 
|  | 266 |  | 
|  | 267 | //! DEBUGGING ONLY: Enable tracking for this object. | 
|  | 268 | // enable -- enable/disable tracking | 
|  | 269 | // retain -- when tracking is enable, if true, then we save a stack trace | 
|  | 270 | //           for each reference and dereference; when retain == false, we | 
|  | 271 | //           match up references and dereferences and keep only the | 
|  | 272 | //           outstanding ones. | 
|  | 273 |  | 
|  | 274 | void                trackMe(bool enable, bool retain); | 
|  | 275 | }; | 
|  | 276 |  | 
|  | 277 | weakref_type*   createWeak(const void* id) const; | 
|  | 278 |  | 
|  | 279 | weakref_type*   getWeakRefs() const; | 
|  | 280 |  | 
|  | 281 | //! DEBUGGING ONLY: Print references held on object. | 
|  | 282 | inline  void            printRefs() const { getWeakRefs()->printRefs(); } | 
|  | 283 |  | 
|  | 284 | //! DEBUGGING ONLY: Enable tracking of object. | 
|  | 285 | inline  void            trackMe(bool enable, bool retain) | 
|  | 286 | { | 
|  | 287 | getWeakRefs()->trackMe(enable, retain); | 
|  | 288 | } | 
|  | 289 |  | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 290 | typedef RefBase basetype; | 
|  | 291 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 292 | protected: | 
|  | 293 | RefBase(); | 
|  | 294 | virtual                 ~RefBase(); | 
| Mathias Agopian | 7f57eac | 2011-06-16 17:15:51 -0700 | [diff] [blame] | 295 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 296 | //! Flags for extendObjectLifetime() | 
|  | 297 | enum { | 
| Mathias Agopian | ad09965 | 2011-08-10 21:07:02 -0700 | [diff] [blame] | 298 | OBJECT_LIFETIME_STRONG  = 0x0000, | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 299 | OBJECT_LIFETIME_WEAK    = 0x0001, | 
| Mathias Agopian | ad09965 | 2011-08-10 21:07:02 -0700 | [diff] [blame] | 300 | OBJECT_LIFETIME_MASK    = 0x0001 | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 301 | }; | 
|  | 302 |  | 
|  | 303 | void            extendObjectLifetime(int32_t mode); | 
|  | 304 |  | 
|  | 305 | //! Flags for onIncStrongAttempted() | 
|  | 306 | enum { | 
|  | 307 | FIRST_INC_STRONG = 0x0001 | 
|  | 308 | }; | 
|  | 309 |  | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 310 | // Invoked after creation of initial strong pointer/reference. | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 311 | virtual void            onFirstRef(); | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 312 | // Invoked when either the last strong reference goes away, or we need to undo | 
|  | 313 | // the effect of an unnecessary onIncStrongAttempted. | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 314 | virtual void            onLastStrongRef(const void* id); | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 315 | // Only called in OBJECT_LIFETIME_WEAK case.  Returns true if OK to promote to | 
|  | 316 | // strong reference. May have side effects if it returns true. | 
|  | 317 | // The first flags argument is always FIRST_INC_STRONG. | 
|  | 318 | // TODO: Remove initial flag argument. | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 319 | virtual bool            onIncStrongAttempted(uint32_t flags, const void* id); | 
| Hans Boehm | 9ba7192 | 2016-07-21 18:56:55 -0700 | [diff] [blame] | 320 | // Invoked in the OBJECT_LIFETIME_WEAK case when the last reference of either | 
|  | 321 | // kind goes away.  Unused. | 
|  | 322 | // TODO: Remove. | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 323 | virtual void            onLastWeakRef(const void* id); | 
|  | 324 |  | 
|  | 325 | private: | 
|  | 326 | friend class weakref_type; | 
|  | 327 | class weakref_impl; | 
|  | 328 |  | 
|  | 329 | RefBase(const RefBase& o); | 
|  | 330 | RefBase&        operator=(const RefBase& o); | 
| Mathias Agopian | ad09965 | 2011-08-10 21:07:02 -0700 | [diff] [blame] | 331 |  | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 332 | private: | 
|  | 333 | friend class ReferenceMover; | 
|  | 334 |  | 
|  | 335 | static void renameRefs(size_t n, const ReferenceRenamer& renamer); | 
|  | 336 |  | 
|  | 337 | static void renameRefId(weakref_type* ref, | 
|  | 338 | const void* old_id, const void* new_id); | 
|  | 339 |  | 
|  | 340 | static void renameRefId(RefBase* ref, | 
|  | 341 | const void* old_id, const void* new_id); | 
|  | 342 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 343 | weakref_impl* const mRefs; | 
|  | 344 | }; | 
|  | 345 |  | 
|  | 346 | // --------------------------------------------------------------------------- | 
|  | 347 |  | 
|  | 348 | template <class T> | 
|  | 349 | class LightRefBase | 
|  | 350 | { | 
|  | 351 | public: | 
|  | 352 | inline LightRefBase() : mCount(0) { } | 
| Igor Murashkin | a27c1e0 | 2012-12-05 16:10:26 -0800 | [diff] [blame] | 353 | inline void incStrong(__attribute__((unused)) const void* id) const { | 
| Hans Boehm | e263e6c | 2016-05-11 18:15:12 -0700 | [diff] [blame] | 354 | mCount.fetch_add(1, std::memory_order_relaxed); | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 355 | } | 
| Igor Murashkin | a27c1e0 | 2012-12-05 16:10:26 -0800 | [diff] [blame] | 356 | inline void decStrong(__attribute__((unused)) const void* id) const { | 
| Hans Boehm | e263e6c | 2016-05-11 18:15:12 -0700 | [diff] [blame] | 357 | if (mCount.fetch_sub(1, std::memory_order_release) == 1) { | 
|  | 358 | std::atomic_thread_fence(std::memory_order_acquire); | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 359 | delete static_cast<const T*>(this); | 
|  | 360 | } | 
|  | 361 | } | 
| Mathias Agopian | 019f8ed | 2009-05-04 14:17:04 -0700 | [diff] [blame] | 362 | //! DEBUGGING ONLY: Get current strong ref count. | 
|  | 363 | inline int32_t getStrongCount() const { | 
| Hans Boehm | e263e6c | 2016-05-11 18:15:12 -0700 | [diff] [blame] | 364 | return mCount.load(std::memory_order_relaxed); | 
| Mathias Agopian | 019f8ed | 2009-05-04 14:17:04 -0700 | [diff] [blame] | 365 | } | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 366 |  | 
|  | 367 | typedef LightRefBase<T> basetype; | 
|  | 368 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 369 | protected: | 
|  | 370 | inline ~LightRefBase() { } | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 371 |  | 
|  | 372 | private: | 
|  | 373 | friend class ReferenceMover; | 
| Greg Kaiser | d9885e7 | 2016-07-08 17:18:07 -0700 | [diff] [blame] | 374 | inline static void renameRefs(size_t /*n*/, | 
|  | 375 | const ReferenceRenamer& /*renamer*/) { } | 
|  | 376 | inline static void renameRefId(T* /*ref*/, | 
|  | 377 | const void* /*old_id*/ , const void* /*new_id*/) { } | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 378 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 379 | private: | 
| Hans Boehm | e263e6c | 2016-05-11 18:15:12 -0700 | [diff] [blame] | 380 | mutable std::atomic<int32_t> mCount; | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 381 | }; | 
|  | 382 |  | 
| John Reck | d83186c | 2014-05-09 15:27:22 -0700 | [diff] [blame] | 383 | // This is a wrapper around LightRefBase that simply enforces a virtual | 
|  | 384 | // destructor to eliminate the template requirement of LightRefBase | 
|  | 385 | class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> { | 
|  | 386 | public: | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 387 | virtual ~VirtualLightRefBase(); | 
| John Reck | d83186c | 2014-05-09 15:27:22 -0700 | [diff] [blame] | 388 | }; | 
|  | 389 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 390 | // --------------------------------------------------------------------------- | 
|  | 391 |  | 
|  | 392 | template <typename T> | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 393 | class wp | 
|  | 394 | { | 
|  | 395 | public: | 
|  | 396 | typedef typename RefBase::weakref_type weakref_type; | 
|  | 397 |  | 
|  | 398 | inline wp() : m_ptr(0) { } | 
|  | 399 |  | 
| Chih-Hung Hsieh | 2a92996 | 2016-08-02 12:14:47 -0700 | [diff] [blame] | 400 | wp(T* other);  // NOLINT(implicit) | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 401 | wp(const wp<T>& other); | 
| Chih-Hung Hsieh | 2a92996 | 2016-08-02 12:14:47 -0700 | [diff] [blame] | 402 | explicit wp(const sp<T>& other); | 
|  | 403 | template<typename U> wp(U* other);  // NOLINT(implicit) | 
|  | 404 | template<typename U> wp(const sp<U>& other);  // NOLINT(implicit) | 
|  | 405 | template<typename U> wp(const wp<U>& other);  // NOLINT(implicit) | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 406 |  | 
|  | 407 | ~wp(); | 
|  | 408 |  | 
|  | 409 | // Assignment | 
|  | 410 |  | 
|  | 411 | wp& operator = (T* other); | 
|  | 412 | wp& operator = (const wp<T>& other); | 
|  | 413 | wp& operator = (const sp<T>& other); | 
|  | 414 |  | 
|  | 415 | template<typename U> wp& operator = (U* other); | 
|  | 416 | template<typename U> wp& operator = (const wp<U>& other); | 
|  | 417 | template<typename U> wp& operator = (const sp<U>& other); | 
|  | 418 |  | 
|  | 419 | void set_object_and_refs(T* other, weakref_type* refs); | 
|  | 420 |  | 
|  | 421 | // promotion to sp | 
|  | 422 |  | 
|  | 423 | sp<T> promote() const; | 
|  | 424 |  | 
|  | 425 | // Reset | 
|  | 426 |  | 
|  | 427 | void clear(); | 
|  | 428 |  | 
|  | 429 | // Accessors | 
|  | 430 |  | 
|  | 431 | inline  weakref_type* get_refs() const { return m_refs; } | 
|  | 432 |  | 
|  | 433 | inline  T* unsafe_get() const { return m_ptr; } | 
|  | 434 |  | 
|  | 435 | // Operators | 
| Mathias Agopian | ff49de7 | 2011-02-09 18:38:55 -0800 | [diff] [blame] | 436 |  | 
|  | 437 | COMPARE_WEAK(==) | 
|  | 438 | COMPARE_WEAK(!=) | 
|  | 439 | COMPARE_WEAK(>) | 
|  | 440 | COMPARE_WEAK(<) | 
|  | 441 | COMPARE_WEAK(<=) | 
|  | 442 | COMPARE_WEAK(>=) | 
|  | 443 |  | 
|  | 444 | inline bool operator == (const wp<T>& o) const { | 
|  | 445 | return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); | 
|  | 446 | } | 
|  | 447 | template<typename U> | 
|  | 448 | inline bool operator == (const wp<U>& o) const { | 
|  | 449 | return m_ptr == o.m_ptr; | 
|  | 450 | } | 
|  | 451 |  | 
|  | 452 | inline bool operator > (const wp<T>& o) const { | 
|  | 453 | return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); | 
|  | 454 | } | 
|  | 455 | template<typename U> | 
|  | 456 | inline bool operator > (const wp<U>& o) const { | 
|  | 457 | return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); | 
|  | 458 | } | 
|  | 459 |  | 
|  | 460 | inline bool operator < (const wp<T>& o) const { | 
|  | 461 | return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); | 
|  | 462 | } | 
|  | 463 | template<typename U> | 
|  | 464 | inline bool operator < (const wp<U>& o) const { | 
|  | 465 | return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); | 
|  | 466 | } | 
|  | 467 | inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } | 
|  | 468 | template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } | 
|  | 469 | inline bool operator <= (const wp<T>& o) const { return !operator > (o); } | 
|  | 470 | template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } | 
|  | 471 | inline bool operator >= (const wp<T>& o) const { return !operator < (o); } | 
|  | 472 | template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 473 |  | 
|  | 474 | private: | 
|  | 475 | template<typename Y> friend class sp; | 
|  | 476 | template<typename Y> friend class wp; | 
|  | 477 |  | 
|  | 478 | T*              m_ptr; | 
|  | 479 | weakref_type*   m_refs; | 
|  | 480 | }; | 
|  | 481 |  | 
|  | 482 | template <typename T> | 
|  | 483 | TextOutput& operator<<(TextOutput& to, const wp<T>& val); | 
|  | 484 |  | 
| Mathias Agopian | ff49de7 | 2011-02-09 18:38:55 -0800 | [diff] [blame] | 485 | #undef COMPARE_WEAK | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 486 |  | 
|  | 487 | // --------------------------------------------------------------------------- | 
|  | 488 | // No user serviceable parts below here. | 
|  | 489 |  | 
|  | 490 | template<typename T> | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 491 | wp<T>::wp(T* other) | 
|  | 492 | : m_ptr(other) | 
|  | 493 | { | 
|  | 494 | if (other) m_refs = other->createWeak(this); | 
|  | 495 | } | 
|  | 496 |  | 
|  | 497 | template<typename T> | 
|  | 498 | wp<T>::wp(const wp<T>& other) | 
|  | 499 | : m_ptr(other.m_ptr), m_refs(other.m_refs) | 
|  | 500 | { | 
|  | 501 | if (m_ptr) m_refs->incWeak(this); | 
|  | 502 | } | 
|  | 503 |  | 
|  | 504 | template<typename T> | 
|  | 505 | wp<T>::wp(const sp<T>& other) | 
|  | 506 | : m_ptr(other.m_ptr) | 
|  | 507 | { | 
|  | 508 | if (m_ptr) { | 
|  | 509 | m_refs = m_ptr->createWeak(this); | 
|  | 510 | } | 
|  | 511 | } | 
|  | 512 |  | 
|  | 513 | template<typename T> template<typename U> | 
|  | 514 | wp<T>::wp(U* other) | 
|  | 515 | : m_ptr(other) | 
|  | 516 | { | 
|  | 517 | if (other) m_refs = other->createWeak(this); | 
|  | 518 | } | 
|  | 519 |  | 
|  | 520 | template<typename T> template<typename U> | 
|  | 521 | wp<T>::wp(const wp<U>& other) | 
|  | 522 | : m_ptr(other.m_ptr) | 
|  | 523 | { | 
|  | 524 | if (m_ptr) { | 
|  | 525 | m_refs = other.m_refs; | 
|  | 526 | m_refs->incWeak(this); | 
|  | 527 | } | 
|  | 528 | } | 
|  | 529 |  | 
|  | 530 | template<typename T> template<typename U> | 
|  | 531 | wp<T>::wp(const sp<U>& other) | 
|  | 532 | : m_ptr(other.m_ptr) | 
|  | 533 | { | 
|  | 534 | if (m_ptr) { | 
|  | 535 | m_refs = m_ptr->createWeak(this); | 
|  | 536 | } | 
|  | 537 | } | 
|  | 538 |  | 
|  | 539 | template<typename T> | 
|  | 540 | wp<T>::~wp() | 
|  | 541 | { | 
|  | 542 | if (m_ptr) m_refs->decWeak(this); | 
|  | 543 | } | 
|  | 544 |  | 
|  | 545 | template<typename T> | 
|  | 546 | wp<T>& wp<T>::operator = (T* other) | 
|  | 547 | { | 
|  | 548 | weakref_type* newRefs = | 
|  | 549 | other ? other->createWeak(this) : 0; | 
|  | 550 | if (m_ptr) m_refs->decWeak(this); | 
|  | 551 | m_ptr = other; | 
|  | 552 | m_refs = newRefs; | 
|  | 553 | return *this; | 
|  | 554 | } | 
|  | 555 |  | 
|  | 556 | template<typename T> | 
|  | 557 | wp<T>& wp<T>::operator = (const wp<T>& other) | 
|  | 558 | { | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 559 | weakref_type* otherRefs(other.m_refs); | 
|  | 560 | T* otherPtr(other.m_ptr); | 
|  | 561 | if (otherPtr) otherRefs->incWeak(this); | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 562 | if (m_ptr) m_refs->decWeak(this); | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 563 | m_ptr = otherPtr; | 
|  | 564 | m_refs = otherRefs; | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 565 | return *this; | 
|  | 566 | } | 
|  | 567 |  | 
|  | 568 | template<typename T> | 
|  | 569 | wp<T>& wp<T>::operator = (const sp<T>& other) | 
|  | 570 | { | 
|  | 571 | weakref_type* newRefs = | 
|  | 572 | other != NULL ? other->createWeak(this) : 0; | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 573 | T* otherPtr(other.m_ptr); | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 574 | if (m_ptr) m_refs->decWeak(this); | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 575 | m_ptr = otherPtr; | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 576 | m_refs = newRefs; | 
|  | 577 | return *this; | 
|  | 578 | } | 
|  | 579 |  | 
|  | 580 | template<typename T> template<typename U> | 
|  | 581 | wp<T>& wp<T>::operator = (U* other) | 
|  | 582 | { | 
|  | 583 | weakref_type* newRefs = | 
|  | 584 | other ? other->createWeak(this) : 0; | 
|  | 585 | if (m_ptr) m_refs->decWeak(this); | 
|  | 586 | m_ptr = other; | 
|  | 587 | m_refs = newRefs; | 
|  | 588 | return *this; | 
|  | 589 | } | 
|  | 590 |  | 
|  | 591 | template<typename T> template<typename U> | 
|  | 592 | wp<T>& wp<T>::operator = (const wp<U>& other) | 
|  | 593 | { | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 594 | weakref_type* otherRefs(other.m_refs); | 
|  | 595 | U* otherPtr(other.m_ptr); | 
|  | 596 | if (otherPtr) otherRefs->incWeak(this); | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 597 | if (m_ptr) m_refs->decWeak(this); | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 598 | m_ptr = otherPtr; | 
|  | 599 | m_refs = otherRefs; | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 600 | return *this; | 
|  | 601 | } | 
|  | 602 |  | 
|  | 603 | template<typename T> template<typename U> | 
|  | 604 | wp<T>& wp<T>::operator = (const sp<U>& other) | 
|  | 605 | { | 
|  | 606 | weakref_type* newRefs = | 
|  | 607 | other != NULL ? other->createWeak(this) : 0; | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 608 | U* otherPtr(other.m_ptr); | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 609 | if (m_ptr) m_refs->decWeak(this); | 
| Mathias Agopian | 7b15167 | 2010-06-24 21:49:02 -0700 | [diff] [blame] | 610 | m_ptr = otherPtr; | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 611 | m_refs = newRefs; | 
|  | 612 | return *this; | 
|  | 613 | } | 
|  | 614 |  | 
|  | 615 | template<typename T> | 
|  | 616 | void wp<T>::set_object_and_refs(T* other, weakref_type* refs) | 
|  | 617 | { | 
|  | 618 | if (other) refs->incWeak(this); | 
|  | 619 | if (m_ptr) m_refs->decWeak(this); | 
|  | 620 | m_ptr = other; | 
|  | 621 | m_refs = refs; | 
|  | 622 | } | 
|  | 623 |  | 
|  | 624 | template<typename T> | 
|  | 625 | sp<T> wp<T>::promote() const | 
|  | 626 | { | 
| Mathias Agopian | 3e0f875 | 2011-02-24 18:12:34 -0800 | [diff] [blame] | 627 | sp<T> result; | 
|  | 628 | if (m_ptr && m_refs->attemptIncStrong(&result)) { | 
|  | 629 | result.set_pointer(m_ptr); | 
|  | 630 | } | 
|  | 631 | return result; | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 632 | } | 
|  | 633 |  | 
|  | 634 | template<typename T> | 
|  | 635 | void wp<T>::clear() | 
|  | 636 | { | 
|  | 637 | if (m_ptr) { | 
|  | 638 | m_refs->decWeak(this); | 
|  | 639 | m_ptr = 0; | 
|  | 640 | } | 
|  | 641 | } | 
|  | 642 |  | 
|  | 643 | template <typename T> | 
|  | 644 | inline TextOutput& operator<<(TextOutput& to, const wp<T>& val) | 
|  | 645 | { | 
| Mathias Agopian | 84a23fa | 2011-02-16 15:23:08 -0800 | [diff] [blame] | 646 | return printWeakPointer(to, val.unsafe_get()); | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 647 | } | 
|  | 648 |  | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 649 | // --------------------------------------------------------------------------- | 
|  | 650 |  | 
|  | 651 | // this class just serves as a namespace so TYPE::moveReferences can stay | 
|  | 652 | // private. | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 653 | class ReferenceMover { | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 654 | public: | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 655 | // it would be nice if we could make sure no extra code is generated | 
|  | 656 | // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase: | 
|  | 657 | // Using a sp<RefBase> override doesn't work; it's a bit like we wanted | 
|  | 658 | // a template<typename TYPE inherits RefBase> template... | 
|  | 659 |  | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 660 | template<typename TYPE> static inline | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 661 | void move_references(sp<TYPE>* dest, sp<TYPE> const* src, size_t n) { | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 662 |  | 
|  | 663 | class Renamer : public ReferenceRenamer { | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 664 | sp<TYPE>* d_; | 
|  | 665 | sp<TYPE> const* s_; | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 666 | virtual void operator()(size_t i) const { | 
|  | 667 | // The id are known to be the sp<>'s this pointer | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 668 | TYPE::renameRefId(d_[i].get(), &s_[i], &d_[i]); | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 669 | } | 
|  | 670 | public: | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 671 | Renamer(sp<TYPE>* d, sp<TYPE> const* s) : d_(d), s_(s) { } | 
| Ukri Niemimuukko | 00e56a2 | 2014-04-29 06:25:28 +0800 | [diff] [blame] | 672 | virtual ~Renamer() { } | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 673 | }; | 
|  | 674 |  | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 675 | memmove(dest, src, n*sizeof(sp<TYPE>)); | 
|  | 676 | TYPE::renameRefs(n, Renamer(dest, src)); | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 677 | } | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 678 |  | 
|  | 679 |  | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 680 | template<typename TYPE> static inline | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 681 | void move_references(wp<TYPE>* dest, wp<TYPE> const* src, size_t n) { | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 682 |  | 
|  | 683 | class Renamer : public ReferenceRenamer { | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 684 | wp<TYPE>* d_; | 
|  | 685 | wp<TYPE> const* s_; | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 686 | virtual void operator()(size_t i) const { | 
|  | 687 | // The id are known to be the wp<>'s this pointer | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 688 | TYPE::renameRefId(d_[i].get_refs(), &s_[i], &d_[i]); | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 689 | } | 
|  | 690 | public: | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 691 | Renamer(wp<TYPE>* rd, wp<TYPE> const* rs) : d_(rd), s_(rs) { } | 
| Ukri Niemimuukko | 00e56a2 | 2014-04-29 06:25:28 +0800 | [diff] [blame] | 692 | virtual ~Renamer() { } | 
| Mathias Agopian | 6cd548c | 2013-03-18 22:27:41 -0700 | [diff] [blame] | 693 | }; | 
|  | 694 |  | 
| Colin Cross | 17b5b82 | 2016-09-15 18:15:37 -0700 | [diff] [blame] | 695 | memmove(dest, src, n*sizeof(wp<TYPE>)); | 
|  | 696 | TYPE::renameRefs(n, Renamer(dest, src)); | 
| Mathias Agopian | b26ea8b | 2011-02-16 20:23:43 -0800 | [diff] [blame] | 697 | } | 
|  | 698 | }; | 
|  | 699 |  | 
|  | 700 | // specialization for moving sp<> and wp<> types. | 
|  | 701 | // these are used by the [Sorted|Keyed]Vector<> implementations | 
|  | 702 | // sp<> and wp<> need to be handled specially, because they do not | 
|  | 703 | // have trivial copy operation in the general case (see RefBase.cpp | 
|  | 704 | // when DEBUG ops are enabled), but can be implemented very | 
|  | 705 | // efficiently in most cases. | 
|  | 706 |  | 
|  | 707 | template<typename TYPE> inline | 
|  | 708 | void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { | 
|  | 709 | ReferenceMover::move_references(d, s, n); | 
|  | 710 | } | 
|  | 711 |  | 
|  | 712 | template<typename TYPE> inline | 
|  | 713 | void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) { | 
|  | 714 | ReferenceMover::move_references(d, s, n); | 
|  | 715 | } | 
|  | 716 |  | 
|  | 717 | template<typename TYPE> inline | 
|  | 718 | void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { | 
|  | 719 | ReferenceMover::move_references(d, s, n); | 
|  | 720 | } | 
|  | 721 |  | 
|  | 722 | template<typename TYPE> inline | 
|  | 723 | void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { | 
|  | 724 | ReferenceMover::move_references(d, s, n); | 
|  | 725 | } | 
|  | 726 |  | 
| The Android Open Source Project | cbb1011 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 727 | }; // namespace android | 
|  | 728 |  | 
|  | 729 | // --------------------------------------------------------------------------- | 
|  | 730 |  | 
|  | 731 | #endif // ANDROID_REF_BASE_H |