| OLD | NEW |
| (Empty) |
| 1 // Copyright 2006 and onwards Google Inc. | |
| 2 // Author: Michael Ellman (with suggestions from jrvb, m3b, toddw, jwray) | |
| 3 // | |
| 4 // A simple reference counted pointer implementation. It is a subset | |
| 5 // of the boost/tr1 shared_ptr class, which is expected to be part of | |
| 6 // the next C++ standard. See section 20.8.10 [util.smartptr] of the | |
| 7 // draft standard for a full description of the standard interface. | |
| 8 // | |
| 9 // Standard features that have been omitted from this implementation include: | |
| 10 // - no custom deallocators - uses delete | |
| 11 // - shared_ptr<T>'s constructor isn't templated: its argument is just T*. | |
| 12 // - no support for smart pointer casts | |
| 13 // - no support for unowned pointers | |
| 14 // - no support for variadic templates or rvalue references | |
| 15 // - no integration with auto_ptr or unique_ptr | |
| 16 // - not exception-safe | |
| 17 // - no overloaded comparison operators (e.g. operator<). They're | |
| 18 // convenient, but they can be explicitly defined outside the class. | |
| 19 // | |
| 20 // It's usually the case that when you want to share an object, there | |
| 21 // is a clear owner that outlives the other users. If that's the case, | |
| 22 // the owner can use scoped_ptr and the rest can use a raw pointer. | |
| 23 // | |
| 24 // A somewhat common design pattern that doesn't have a clear object | |
| 25 // owner is when there is a shared container in which older versions | |
| 26 // of an object are replaced with newer versions. The objects should be | |
| 27 // deleted only when (a) they are replaced with a new version and (b) | |
| 28 // there are no outside users of the old version. Replacing raw pointers | |
| 29 // in the implementation with shared_ptr's ensures that the accounting | |
| 30 // and object lifetimes are handled appropriately. | |
| 31 // | |
| 32 // The typical usage is as follows. | |
| 33 // | |
| 34 // 1. Functions using shared_ptr's should declare shared_ptr parameters to | |
| 35 // be of type const reference since the caller will still have its own | |
| 36 // shared_ptr for the entire call. | |
| 37 // | |
| 38 // void foo(const shared_ptr<T>& param) | |
| 39 // | |
| 40 // 2. Functions setting shared_ptr's should declare shared_ptr parameters | |
| 41 // to be of pointer type. | |
| 42 // | |
| 43 // typedef map<Key, shared_ptr<Value> > MyMap; | |
| 44 // void GetAndSharedObject(const Key& key, shared_ptr<Value>* value) { | |
| 45 // ReaderMutexLock l(&lock_); | |
| 46 // MyMap::iterator iter = shared_container.find(key); | |
| 47 // *value = iter->second; | |
| 48 // } | |
| 49 // | |
| 50 // Thread Safety: | |
| 51 // Once constructed, a shared_ptr has the same thread-safety as built-in | |
| 52 // types. In particular, it is safe to read a shared object simultaneously | |
| 53 // from multiple threads. | |
| 54 // | |
| 55 // Weak ptrs | |
| 56 // The weak_ptr auxiliary class (see clause 20.8.10.3 of the draft standard) | |
| 57 // is used to break ownership cycles. A weak_ptr points to an object that's | |
| 58 // owned by a shared_ptr, but the weak_ptr is an observer, not an owner. When | |
| 59 // the last shared_ptr that points to the object disappears, the weak_ptr | |
| 60 // expires, at which point the expired() member function will return true. | |
| 61 // | |
| 62 // You can't directly get a raw pointer from weak_ptr, i.e. it has no get() | |
| 63 // or operator*() member function. (These features were intentionally left out | |
| 64 // to avoid the risk of dangling pointers.) To access a weak_ptr's pointed-to | |
| 65 // object, use lock() to obtain a temporary shared_ptr. | |
| 66 // | |
| 67 // enable_shared_from_this | |
| 68 // A user-defined class T can inherit from enable_shared_from_this<T> (see | |
| 69 // clause 20.8.10.5 of the draft standard) to inherit T::shared_from_this(), | |
| 70 // which returns a shared_ptr pointing to *this. It is similar to weak_ptr in | |
| 71 // that there must already be at least one shared_ptr instance that owns | |
| 72 // *this. | |
| 73 | |
| 74 #ifndef BAR_COMMON_SHARED_PTR_H_ | |
| 75 #define BAR_COMMON_SHARED_PTR_H_ | |
| 76 | |
| 77 #include <windows.h> | |
| 78 #include <algorithm> // for swap | |
| 79 | |
| 80 template <typename T> class shared_ptr; | |
| 81 template <typename T> class weak_ptr; | |
| 82 | |
| 83 // This class is an internal implementation detail for shared_ptr. If two | |
| 84 // shared_ptrs point to the same object, they also share a control block. | |
| 85 // An "empty" shared_pointer refers to NULL and also has a NULL control block. | |
| 86 // It contains all of the state that's needed for reference counting or any | |
| 87 // other kind of resource management. In this implementation the control block | |
| 88 // happens to consist of two atomic words, the reference count (the number | |
| 89 // of shared_ptrs that share ownership of the object) and the weak count | |
| 90 // (the number of weak_ptrs that observe the object, plus 1 if the | |
| 91 // refcount is nonzero). | |
| 92 // | |
| 93 // The "plus 1" is to prevent a race condition in the shared_ptr and | |
| 94 // weak_ptr destructors. We need to make sure the control block is | |
| 95 // only deleted once, so we need to make sure that at most one | |
| 96 // object sees the weak count decremented from 1 to 0. | |
| 97 class SharedPtrControlBlock { | |
| 98 template <typename T> friend class shared_ptr; | |
| 99 template <typename T> friend class weak_ptr; | |
| 100 private: | |
| 101 SharedPtrControlBlock() : refcount_(1), weak_count_(1) { } | |
| 102 LONG refcount_; | |
| 103 LONG weak_count_; | |
| 104 }; | |
| 105 | |
| 106 // Forward declaration. The class is defined below. | |
| 107 template <typename T> class enable_shared_from_this; | |
| 108 | |
| 109 template <typename T> | |
| 110 class shared_ptr { | |
| 111 template <typename U> friend class weak_ptr; | |
| 112 public: | |
| 113 typedef T element_type; | |
| 114 | |
| 115 explicit shared_ptr(T* ptr = NULL) | |
| 116 : ptr_(ptr), | |
| 117 control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) { | |
| 118 // If p is non-null and T inherits from enable_shared_from_this, we | |
| 119 // set up the data that shared_from_this needs. | |
| 120 MaybeSetupWeakThis(ptr); | |
| 121 } | |
| 122 | |
| 123 // Copy constructor: makes this object a copy of ptr, and increments | |
| 124 // the reference count. | |
| 125 template <typename U> | |
| 126 shared_ptr(const shared_ptr<U>& ptr) | |
| 127 : ptr_(NULL), | |
| 128 control_block_(NULL) { | |
| 129 Initialize(ptr); | |
| 130 } | |
| 131 // Need non-templated version to prevent the compiler-generated default | |
| 132 shared_ptr(const shared_ptr<T>& ptr) | |
| 133 : ptr_(NULL), | |
| 134 control_block_(NULL) { | |
| 135 Initialize(ptr); | |
| 136 } | |
| 137 | |
| 138 // Assignment operator. Replaces the existing shared_ptr with ptr. | |
| 139 // Increment ptr's reference count and decrement the one being replaced. | |
| 140 template <typename U> | |
| 141 shared_ptr<T>& operator=(const shared_ptr<U>& ptr) { | |
| 142 if (ptr_ != ptr.ptr_) { | |
| 143 shared_ptr<T> me(ptr); // will hold our previous state to be destroyed. | |
| 144 swap(me); | |
| 145 } | |
| 146 return *this; | |
| 147 } | |
| 148 | |
| 149 // Need non-templated version to prevent the compiler-generated default | |
| 150 shared_ptr<T>& operator=(const shared_ptr<T>& ptr) { | |
| 151 if (ptr_ != ptr.ptr_) { | |
| 152 shared_ptr<T> me(ptr); // will hold our previous state to be destroyed. | |
| 153 swap(me); | |
| 154 } | |
| 155 return *this; | |
| 156 } | |
| 157 | |
| 158 // TODO(austern): Consider providing this constructor. The draft C++ standard | |
| 159 // (20.8.10.2.1) includes it. However, it says that this constructor throws | |
| 160 // a bad_weak_ptr exception when ptr is expired. Is it better to provide this | |
| 161 // constructor and make it do something else, like fail with a CHECK, or to | |
| 162 // leave this constructor out entirely? | |
| 163 // | |
| 164 // template <typename U> | |
| 165 // shared_ptr(const weak_ptr<U>& ptr); | |
| 166 | |
| 167 ~shared_ptr() { | |
| 168 if (ptr_ != NULL) { | |
| 169 if (::InterlockedDecrement(&control_block_->refcount_) == 0) { | |
| 170 delete ptr_; | |
| 171 | |
| 172 // weak_count_ is defined as the number of weak_ptrs that observe | |
| 173 // ptr_, plus 1 if refcount_ is nonzero. | |
| 174 if (::InterlockedDecrement(&control_block_->weak_count_) == 0) { | |
| 175 delete control_block_; | |
| 176 } | |
| 177 } | |
| 178 } | |
| 179 } | |
| 180 | |
| 181 // Replaces underlying raw pointer with the one passed in. The reference | |
| 182 // count is set to one (or zero if the pointer is NULL) for the pointer | |
| 183 // being passed in and decremented for the one being replaced. | |
| 184 void reset(T* p = NULL) { | |
| 185 if (p != ptr_) { | |
| 186 shared_ptr<T> tmp(p); | |
| 187 tmp.swap(*this); | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 // Exchanges the contents of this with the contents of r. This function | |
| 192 // supports more efficient swapping since it eliminates the need for a | |
| 193 // temporary shared_ptr object. | |
| 194 void swap(shared_ptr<T>& r) { | |
| 195 std::swap(ptr_, r.ptr_); | |
| 196 std::swap(control_block_, r.control_block_); | |
| 197 } | |
| 198 | |
| 199 // The following function is useful for gaining access to the underlying | |
| 200 // pointer when a shared_ptr remains in scope so the reference-count is | |
| 201 // known to be > 0 (e.g. for parameter passing). | |
| 202 T* get() const { | |
| 203 return ptr_; | |
| 204 } | |
| 205 | |
| 206 T& operator*() const { | |
| 207 return *ptr_; | |
| 208 } | |
| 209 | |
| 210 T* operator->() const { | |
| 211 return ptr_; | |
| 212 } | |
| 213 | |
| 214 LONG use_count() const { | |
| 215 return control_block_ ? control_block_->refcount_ : 1; | |
| 216 } | |
| 217 | |
| 218 bool unique() const { | |
| 219 return use_count() == 1; | |
| 220 } | |
| 221 | |
| 222 private: | |
| 223 // If r is non-empty, initialize *this to share ownership with r, | |
| 224 // increasing the underlying reference count. | |
| 225 // If r is empty, *this remains empty. | |
| 226 // Requires: this is empty, namely this->ptr_ == NULL. | |
| 227 template <typename U> | |
| 228 void Initialize(const shared_ptr<U>& r) { | |
| 229 if (r.control_block_ != NULL) { | |
| 230 ::InterlockedIncrement(&r.control_block_->refcount_); | |
| 231 | |
| 232 ptr_ = r.ptr_; | |
| 233 control_block_ = r.control_block_; | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 // Helper function for the constructor that takes a raw pointer. If T | |
| 238 // doesn't inherit from enable_shared_from_this<T> then we have nothing to | |
| 239 // do, so this function is trivial and inline. The other version is declared | |
| 240 // out of line, after the class definition of enable_shared_from_this. | |
| 241 void MaybeSetupWeakThis(enable_shared_from_this<T>* ptr); | |
| 242 void MaybeSetupWeakThis(...) { } | |
| 243 | |
| 244 T* ptr_; | |
| 245 SharedPtrControlBlock* control_block_; | |
| 246 | |
| 247 template <typename U> | |
| 248 friend class shared_ptr; | |
| 249 }; | |
| 250 | |
| 251 // Matches the interface of std::swap as an aid to generic programming. | |
| 252 template <typename T> void swap(shared_ptr<T>& r, shared_ptr<T>& s) { | |
| 253 r.swap(s); | |
| 254 } | |
| 255 | |
| 256 // See comments at the top of the file for a description of why this | |
| 257 // class exists, and the draft C++ standard (as of July 2009 the | |
| 258 // latest draft is N2914) for the detailed specification. | |
| 259 template <typename T> | |
| 260 class weak_ptr { | |
| 261 template <typename U> friend class weak_ptr; | |
| 262 public: | |
| 263 typedef T element_type; | |
| 264 | |
| 265 // Create an empty (i.e. already expired) weak_ptr. | |
| 266 weak_ptr() : ptr_(NULL), control_block_(NULL) { } | |
| 267 | |
| 268 // Create a weak_ptr that observes the same object that ptr points | |
| 269 // to. Note that there is no race condition here: we know that the | |
| 270 // control block can't disappear while we're looking at it because | |
| 271 // it is owned by at least one shared_ptr, ptr. | |
| 272 template <typename U> weak_ptr(const shared_ptr<U>& ptr) { | |
| 273 CopyFrom(ptr.ptr_, ptr.control_block_); | |
| 274 } | |
| 275 | |
| 276 // Copy a weak_ptr. The object it points to might disappear, but we | |
| 277 // don't care: we're only working with the control block, and it can't | |
| 278 // disappear while we're looking at because it's owned by at least one | |
| 279 // weak_ptr, ptr. | |
| 280 template <typename U> weak_ptr(const weak_ptr<U>& ptr) { | |
| 281 CopyFrom(ptr.ptr_, ptr.control_block_); | |
| 282 } | |
| 283 | |
| 284 // Need non-templated version to prevent default copy constructor | |
| 285 weak_ptr(const weak_ptr& ptr) { | |
| 286 CopyFrom(ptr.ptr_, ptr.control_block_); | |
| 287 } | |
| 288 | |
| 289 // Destroy the weak_ptr. If no shared_ptr owns the control block, and if | |
| 290 // we are the last weak_ptr to own it, then it can be deleted. Note that | |
| 291 // weak_count_ is defined as the number of weak_ptrs sharing this control | |
| 292 // block, plus 1 if there are any shared_ptrs. We therefore know that it's | |
| 293 // safe to delete the control block when weak_count_ reaches 0, without | |
| 294 // having to perform any additional tests. | |
| 295 ~weak_ptr() { | |
| 296 if (control_block_ != NULL && | |
| 297 ::InterlockedDecrement(&control_block_->weak_count_) == 0) { | |
| 298 delete control_block_; | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 weak_ptr& operator=(const weak_ptr& ptr) { | |
| 303 if (&ptr != this) { | |
| 304 weak_ptr tmp(ptr); | |
| 305 tmp.swap(*this); | |
| 306 } | |
| 307 return *this; | |
| 308 } | |
| 309 template <typename U> weak_ptr& operator=(const weak_ptr<U>& ptr) { | |
| 310 weak_ptr tmp(ptr); | |
| 311 tmp.swap(*this); | |
| 312 return *this; | |
| 313 } | |
| 314 template <typename U> weak_ptr& operator=(const shared_ptr<U>& ptr) { | |
| 315 weak_ptr tmp(ptr); | |
| 316 tmp.swap(*this); | |
| 317 return *this; | |
| 318 } | |
| 319 | |
| 320 void swap(weak_ptr& ptr) { | |
| 321 std::swap(ptr_, ptr.ptr_); | |
| 322 std::swap(control_block_, ptr.control_block_); | |
| 323 } | |
| 324 | |
| 325 void reset() { | |
| 326 weak_ptr tmp; | |
| 327 tmp.swap(*this); | |
| 328 } | |
| 329 | |
| 330 // Return the number of shared_ptrs that own the object we are observing. | |
| 331 // Note that this number can be 0 (if this pointer has expired). | |
| 332 LONG use_count() const { | |
| 333 return control_block_ != NULL ? control_block_->refcount_ : 0; | |
| 334 } | |
| 335 | |
| 336 bool expired() const { return use_count() == 0; } | |
| 337 | |
| 338 // Return a shared_ptr that owns the object we are observing. If we | |
| 339 // have expired, the shared_ptr will be empty. We have to be careful | |
| 340 // about concurrency, though, since some other thread might be | |
| 341 // destroying the last owning shared_ptr while we're in this | |
| 342 // function. We want to increment the refcount only if it's nonzero | |
| 343 // and get the new value, and we want that whole operation to be | |
| 344 // atomic. | |
| 345 shared_ptr<T> lock() const { | |
| 346 shared_ptr<T> result; | |
| 347 if (control_block_ != NULL) { | |
| 348 LONG old_refcount; | |
| 349 do { | |
| 350 old_refcount = control_block_->refcount_; | |
| 351 if (old_refcount == 0) | |
| 352 break; | |
| 353 } while (old_refcount != | |
| 354 ::InterlockedCompareExchange( | |
| 355 &control_block_->refcount_, old_refcount + 1, | |
| 356 old_refcount)); | |
| 357 if (old_refcount > 0) { | |
| 358 result.ptr_ = ptr_; | |
| 359 result.control_block_ = control_block_; | |
| 360 } | |
| 361 } | |
| 362 | |
| 363 return result; | |
| 364 } | |
| 365 | |
| 366 private: | |
| 367 void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) { | |
| 368 ptr_ = ptr; | |
| 369 control_block_ = control_block; | |
| 370 if (control_block_ != NULL) | |
| 371 ::InterlockedIncrement(&control_block_->weak_count_); | |
| 372 } | |
| 373 | |
| 374 private: | |
| 375 element_type* ptr_; | |
| 376 SharedPtrControlBlock* control_block_; | |
| 377 }; | |
| 378 | |
| 379 template <typename T> void swap(weak_ptr<T>& r, weak_ptr<T>& s) { | |
| 380 r.swap(s); | |
| 381 } | |
| 382 | |
| 383 // See comments at the top of the file for a description of why this class | |
| 384 // exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009 | |
| 385 // the latest draft is N2914) for the detailed specification. | |
| 386 template <typename T> | |
| 387 class enable_shared_from_this { | |
| 388 friend class shared_ptr<T>; | |
| 389 public: | |
| 390 // Precondition: there must be a shared_ptr that owns *this and that was | |
| 391 // created, directly or indirectly, from a raw pointer of type T*. (The | |
| 392 // latter part of the condition is technical but not quite redundant; it | |
| 393 // rules out some complicated uses involving inheritance hierarchies.) | |
| 394 shared_ptr<T> shared_from_this() { | |
| 395 // Behavior is undefined if the precondition isn't satisfied; we choose | |
| 396 // to die with an access violation exception. | |
| 397 #if DEBUG | |
| 398 if (weak_this_.expired()) { | |
| 399 // No shared_ptr owns this object. | |
| 400 *static_cast<int*>(NULL) = 0; | |
| 401 } | |
| 402 #endif | |
| 403 return weak_this_.lock(); | |
| 404 } | |
| 405 shared_ptr<const T> shared_from_this() const { | |
| 406 #if DEBUG | |
| 407 if (weak_this_.expired()) { | |
| 408 // No shared_ptr owns this object. | |
| 409 *static_cast<int*>(NULL) = 0; | |
| 410 } | |
| 411 #endif | |
| 412 return weak_this_.lock(); | |
| 413 } | |
| 414 | |
| 415 protected: | |
| 416 enable_shared_from_this() { } | |
| 417 enable_shared_from_this(const enable_shared_from_this& other) { } | |
| 418 enable_shared_from_this& operator=(const enable_shared_from_this& other) { | |
| 419 return *this; | |
| 420 } | |
| 421 ~enable_shared_from_this() { } | |
| 422 | |
| 423 private: | |
| 424 weak_ptr<T> weak_this_; | |
| 425 }; | |
| 426 | |
| 427 // This is a helper function called by shared_ptr's constructor from a raw | |
| 428 // pointer. If T inherits from enable_shared_from_this<T>, it sets up | |
| 429 // weak_this_ so that shared_from_this works correctly. If T does not inherit | |
| 430 // from weak_this we get a different overload, defined inline, which does | |
| 431 // nothing. | |
| 432 template<typename T> | |
| 433 void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) { | |
| 434 if (ptr) | |
| 435 ptr->weak_this_ = *this; | |
| 436 } | |
| 437 | |
| 438 #endif // BAR_COMMON_SHARED_PTR_H_ | |
| OLD | NEW |