Brian Silverman | 9c614bc | 2016-02-15 20:20:02 -0500 | [diff] [blame^] | 1 | // Protocol Buffers - Google's data interchange format |
| 2 | // Copyright 2014 Google Inc. All rights reserved. |
| 3 | // https://developers.google.com/protocol-buffers/ |
| 4 | // |
| 5 | // Redistribution and use in source and binary forms, with or without |
| 6 | // modification, are permitted provided that the following conditions are |
| 7 | // met: |
| 8 | // |
| 9 | // * Redistributions of source code must retain the above copyright |
| 10 | // notice, this list of conditions and the following disclaimer. |
| 11 | // * Redistributions in binary form must reproduce the above |
| 12 | // copyright notice, this list of conditions and the following disclaimer |
| 13 | // in the documentation and/or other materials provided with the |
| 14 | // distribution. |
| 15 | // * Neither the name of Google Inc. nor the names of its |
| 16 | // contributors may be used to endorse or promote products derived from |
| 17 | // this software without specific prior written permission. |
| 18 | // |
| 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | |
| 31 | // from google3/util/gtl/shared_ptr.h |
| 32 | |
| 33 | #ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__ |
| 34 | #define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__ |
| 35 | |
| 36 | #include <google/protobuf/stubs/atomicops.h> |
| 37 | |
| 38 | #include <algorithm> // for swap |
| 39 | #include <stddef.h> |
| 40 | #include <memory> |
| 41 | |
| 42 | namespace google { |
| 43 | namespace protobuf { |
| 44 | namespace internal { |
| 45 | |
| 46 | // Alias to std::shared_ptr for any C++11 platform, |
| 47 | // and for any supported MSVC compiler. |
| 48 | #if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \ |
| 49 | (defined(COMPILER_MSVC) || defined(LANG_CXX11)) |
| 50 | #define UTIL_GTL_USE_STD_SHARED_PTR 1 |
| 51 | #endif |
| 52 | |
| 53 | #if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR |
| 54 | |
| 55 | // These are transitional. They will be going away soon. |
| 56 | // Please just #include <memory> and just type std::shared_ptr yourself, instead |
| 57 | // of relying on this file. |
| 58 | // |
| 59 | // Migration doc: http://go/std-shared-ptr-lsc |
| 60 | using std::enable_shared_from_this; |
| 61 | using std::shared_ptr; |
| 62 | using std::static_pointer_cast; |
| 63 | using std::weak_ptr; |
| 64 | |
| 65 | #else // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0. |
| 66 | |
| 67 | // For everything else there is the google3 implementation. |
| 68 | inline bool RefCountDec(volatile Atomic32 *ptr) { |
| 69 | return Barrier_AtomicIncrement(ptr, -1) != 0; |
| 70 | } |
| 71 | |
| 72 | inline void RefCountInc(volatile Atomic32 *ptr) { |
| 73 | NoBarrier_AtomicIncrement(ptr, 1); |
| 74 | } |
| 75 | |
| 76 | template <typename T> class shared_ptr; |
| 77 | template <typename T> class weak_ptr; |
| 78 | |
| 79 | // This class is an internal implementation detail for shared_ptr. If two |
| 80 | // shared_ptrs point to the same object, they also share a control block. |
| 81 | // An "empty" shared_pointer refers to NULL and also has a NULL control block. |
| 82 | // It contains all of the state that's needed for reference counting or any |
| 83 | // other kind of resource management. In this implementation the control block |
| 84 | // happens to consist of two atomic words, the reference count (the number |
| 85 | // of shared_ptrs that share ownership of the object) and the weak count |
| 86 | // (the number of weak_ptrs that observe the object, plus 1 if the |
| 87 | // refcount is nonzero). |
| 88 | // |
| 89 | // The "plus 1" is to prevent a race condition in the shared_ptr and |
| 90 | // weak_ptr destructors. We need to make sure the control block is |
| 91 | // only deleted once, so we need to make sure that at most one |
| 92 | // object sees the weak count decremented from 1 to 0. |
| 93 | class SharedPtrControlBlock { |
| 94 | template <typename T> friend class shared_ptr; |
| 95 | template <typename T> friend class weak_ptr; |
| 96 | private: |
| 97 | SharedPtrControlBlock() : refcount_(1), weak_count_(1) { } |
| 98 | Atomic32 refcount_; |
| 99 | Atomic32 weak_count_; |
| 100 | }; |
| 101 | |
| 102 | // Forward declaration. The class is defined below. |
| 103 | template <typename T> class enable_shared_from_this; |
| 104 | |
| 105 | template <typename T> |
| 106 | class shared_ptr { |
| 107 | template <typename U> friend class weak_ptr; |
| 108 | public: |
| 109 | typedef T element_type; |
| 110 | |
| 111 | shared_ptr() : ptr_(NULL), control_block_(NULL) {} |
| 112 | |
| 113 | explicit shared_ptr(T* ptr) |
| 114 | : ptr_(ptr), |
| 115 | control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) { |
| 116 | // If p is non-null and T inherits from enable_shared_from_this, we |
| 117 | // set up the data that shared_from_this needs. |
| 118 | MaybeSetupWeakThis(ptr); |
| 119 | } |
| 120 | |
| 121 | // Copy constructor: makes this object a copy of ptr, and increments |
| 122 | // the reference count. |
| 123 | template <typename U> |
| 124 | shared_ptr(const shared_ptr<U>& ptr) |
| 125 | : ptr_(NULL), |
| 126 | control_block_(NULL) { |
| 127 | Initialize(ptr); |
| 128 | } |
| 129 | // Need non-templated version to prevent the compiler-generated default |
| 130 | shared_ptr(const shared_ptr<T>& ptr) |
| 131 | : ptr_(NULL), |
| 132 | control_block_(NULL) { |
| 133 | Initialize(ptr); |
| 134 | } |
| 135 | |
| 136 | // Assignment operator. Replaces the existing shared_ptr with ptr. |
| 137 | // Increment ptr's reference count and decrement the one being replaced. |
| 138 | template <typename U> |
| 139 | shared_ptr<T>& operator=(const shared_ptr<U>& ptr) { |
| 140 | if (ptr_ != ptr.ptr_) { |
| 141 | shared_ptr<T> me(ptr); // will hold our previous state to be destroyed. |
| 142 | swap(me); |
| 143 | } |
| 144 | return *this; |
| 145 | } |
| 146 | |
| 147 | // Need non-templated version to prevent the compiler-generated default |
| 148 | shared_ptr<T>& operator=(const shared_ptr<T>& ptr) { |
| 149 | if (ptr_ != ptr.ptr_) { |
| 150 | shared_ptr<T> me(ptr); // will hold our previous state to be destroyed. |
| 151 | swap(me); |
| 152 | } |
| 153 | return *this; |
| 154 | } |
| 155 | |
| 156 | // TODO(austern): Consider providing this constructor. The draft C++ standard |
| 157 | // (20.8.10.2.1) includes it. However, it says that this constructor throws |
| 158 | // a bad_weak_ptr exception when ptr is expired. Is it better to provide this |
| 159 | // constructor and make it do something else, like fail with a CHECK, or to |
| 160 | // leave this constructor out entirely? |
| 161 | // |
| 162 | // template <typename U> |
| 163 | // shared_ptr(const weak_ptr<U>& ptr); |
| 164 | |
| 165 | ~shared_ptr() { |
| 166 | if (ptr_ != NULL) { |
| 167 | if (!RefCountDec(&control_block_->refcount_)) { |
| 168 | delete ptr_; |
| 169 | |
| 170 | // weak_count_ is defined as the number of weak_ptrs that observe |
| 171 | // ptr_, plus 1 if refcount_ is nonzero. |
| 172 | if (!RefCountDec(&control_block_->weak_count_)) { |
| 173 | delete control_block_; |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | // Replaces underlying raw pointer with the one passed in. The reference |
| 180 | // count is set to one (or zero if the pointer is NULL) for the pointer |
| 181 | // being passed in and decremented for the one being replaced. |
| 182 | // |
| 183 | // If you have a compilation error with this code, make sure you aren't |
| 184 | // passing NULL, nullptr, or 0 to this function. Call reset without an |
| 185 | // argument to reset to a null ptr. |
| 186 | template <typename Y> |
| 187 | void reset(Y* p) { |
| 188 | if (p != ptr_) { |
| 189 | shared_ptr<T> tmp(p); |
| 190 | tmp.swap(*this); |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | void reset() { |
| 195 | reset(static_cast<T*>(NULL)); |
| 196 | } |
| 197 | |
| 198 | // Exchanges the contents of this with the contents of r. This function |
| 199 | // supports more efficient swapping since it eliminates the need for a |
| 200 | // temporary shared_ptr object. |
| 201 | void swap(shared_ptr<T>& r) { |
| 202 | using std::swap; // http://go/using-std-swap |
| 203 | swap(ptr_, r.ptr_); |
| 204 | swap(control_block_, r.control_block_); |
| 205 | } |
| 206 | |
| 207 | // The following function is useful for gaining access to the underlying |
| 208 | // pointer when a shared_ptr remains in scope so the reference-count is |
| 209 | // known to be > 0 (e.g. for parameter passing). |
| 210 | T* get() const { |
| 211 | return ptr_; |
| 212 | } |
| 213 | |
| 214 | T& operator*() const { |
| 215 | return *ptr_; |
| 216 | } |
| 217 | |
| 218 | T* operator->() const { |
| 219 | return ptr_; |
| 220 | } |
| 221 | |
| 222 | long use_count() const { |
| 223 | return control_block_ ? control_block_->refcount_ : 1; |
| 224 | } |
| 225 | |
| 226 | bool unique() const { |
| 227 | return use_count() == 1; |
| 228 | } |
| 229 | |
| 230 | private: |
| 231 | // If r is non-empty, initialize *this to share ownership with r, |
| 232 | // increasing the underlying reference count. |
| 233 | // If r is empty, *this remains empty. |
| 234 | // Requires: this is empty, namely this->ptr_ == NULL. |
| 235 | template <typename U> |
| 236 | void Initialize(const shared_ptr<U>& r) { |
| 237 | // This performs a static_cast on r.ptr_ to U*, which is a no-op since it |
| 238 | // is already a U*. So initialization here requires that r.ptr_ is |
| 239 | // implicitly convertible to T*. |
| 240 | InitializeWithStaticCast<U>(r); |
| 241 | } |
| 242 | |
| 243 | // Initializes *this as described in Initialize, but additionally performs a |
| 244 | // static_cast from r.ptr_ (V*) to U*. |
| 245 | // NOTE(gfc): We'd need a more general form to support const_pointer_cast and |
| 246 | // dynamic_pointer_cast, but those operations are sufficiently discouraged |
| 247 | // that supporting static_pointer_cast is sufficient. |
| 248 | template <typename U, typename V> |
| 249 | void InitializeWithStaticCast(const shared_ptr<V>& r) { |
| 250 | if (r.control_block_ != NULL) { |
| 251 | RefCountInc(&r.control_block_->refcount_); |
| 252 | |
| 253 | ptr_ = static_cast<U*>(r.ptr_); |
| 254 | control_block_ = r.control_block_; |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | // Helper function for the constructor that takes a raw pointer. If T |
| 259 | // doesn't inherit from enable_shared_from_this<T> then we have nothing to |
| 260 | // do, so this function is trivial and inline. The other version is declared |
| 261 | // out of line, after the class definition of enable_shared_from_this. |
| 262 | void MaybeSetupWeakThis(enable_shared_from_this<T>* ptr); |
| 263 | void MaybeSetupWeakThis(...) { } |
| 264 | |
| 265 | T* ptr_; |
| 266 | SharedPtrControlBlock* control_block_; |
| 267 | |
| 268 | #ifndef SWIG |
| 269 | template <typename U> |
| 270 | friend class shared_ptr; |
| 271 | |
| 272 | template <typename U, typename V> |
| 273 | friend shared_ptr<U> static_pointer_cast(const shared_ptr<V>& rhs); |
| 274 | #endif |
| 275 | }; |
| 276 | |
| 277 | // Matches the interface of std::swap as an aid to generic programming. |
| 278 | template <typename T> void swap(shared_ptr<T>& r, shared_ptr<T>& s) { |
| 279 | r.swap(s); |
| 280 | } |
| 281 | |
| 282 | template <typename T, typename U> |
| 283 | shared_ptr<T> static_pointer_cast(const shared_ptr<U>& rhs) { |
| 284 | shared_ptr<T> lhs; |
| 285 | lhs.template InitializeWithStaticCast<T>(rhs); |
| 286 | return lhs; |
| 287 | } |
| 288 | |
| 289 | // See comments at the top of the file for a description of why this |
| 290 | // class exists, and the draft C++ standard (as of July 2009 the |
| 291 | // latest draft is N2914) for the detailed specification. |
| 292 | template <typename T> |
| 293 | class weak_ptr { |
| 294 | template <typename U> friend class weak_ptr; |
| 295 | public: |
| 296 | typedef T element_type; |
| 297 | |
| 298 | // Create an empty (i.e. already expired) weak_ptr. |
| 299 | weak_ptr() : ptr_(NULL), control_block_(NULL) { } |
| 300 | |
| 301 | // Create a weak_ptr that observes the same object that ptr points |
| 302 | // to. Note that there is no race condition here: we know that the |
| 303 | // control block can't disappear while we're looking at it because |
| 304 | // it is owned by at least one shared_ptr, ptr. |
| 305 | template <typename U> weak_ptr(const shared_ptr<U>& ptr) { |
| 306 | CopyFrom(ptr.ptr_, ptr.control_block_); |
| 307 | } |
| 308 | |
| 309 | // Copy a weak_ptr. The object it points to might disappear, but we |
| 310 | // don't care: we're only working with the control block, and it can't |
| 311 | // disappear while we're looking at because it's owned by at least one |
| 312 | // weak_ptr, ptr. |
| 313 | template <typename U> weak_ptr(const weak_ptr<U>& ptr) { |
| 314 | CopyFrom(ptr.ptr_, ptr.control_block_); |
| 315 | } |
| 316 | |
| 317 | // Need non-templated version to prevent default copy constructor |
| 318 | weak_ptr(const weak_ptr& ptr) { |
| 319 | CopyFrom(ptr.ptr_, ptr.control_block_); |
| 320 | } |
| 321 | |
| 322 | // Destroy the weak_ptr. If no shared_ptr owns the control block, and if |
| 323 | // we are the last weak_ptr to own it, then it can be deleted. Note that |
| 324 | // weak_count_ is defined as the number of weak_ptrs sharing this control |
| 325 | // block, plus 1 if there are any shared_ptrs. We therefore know that it's |
| 326 | // safe to delete the control block when weak_count_ reaches 0, without |
| 327 | // having to perform any additional tests. |
| 328 | ~weak_ptr() { |
| 329 | if (control_block_ != NULL && |
| 330 | !RefCountDec(&control_block_->weak_count_)) { |
| 331 | delete control_block_; |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | weak_ptr& operator=(const weak_ptr& ptr) { |
| 336 | if (&ptr != this) { |
| 337 | weak_ptr tmp(ptr); |
| 338 | tmp.swap(*this); |
| 339 | } |
| 340 | return *this; |
| 341 | } |
| 342 | template <typename U> weak_ptr& operator=(const weak_ptr<U>& ptr) { |
| 343 | weak_ptr tmp(ptr); |
| 344 | tmp.swap(*this); |
| 345 | return *this; |
| 346 | } |
| 347 | template <typename U> weak_ptr& operator=(const shared_ptr<U>& ptr) { |
| 348 | weak_ptr tmp(ptr); |
| 349 | tmp.swap(*this); |
| 350 | return *this; |
| 351 | } |
| 352 | |
| 353 | void swap(weak_ptr& ptr) { |
| 354 | using std::swap; // http://go/using-std-swap |
| 355 | swap(ptr_, ptr.ptr_); |
| 356 | swap(control_block_, ptr.control_block_); |
| 357 | } |
| 358 | |
| 359 | void reset() { |
| 360 | weak_ptr tmp; |
| 361 | tmp.swap(*this); |
| 362 | } |
| 363 | |
| 364 | // Return the number of shared_ptrs that own the object we are observing. |
| 365 | // Note that this number can be 0 (if this pointer has expired). |
| 366 | long use_count() const { |
| 367 | return control_block_ != NULL ? control_block_->refcount_ : 0; |
| 368 | } |
| 369 | |
| 370 | bool expired() const { return use_count() == 0; } |
| 371 | |
| 372 | // Return a shared_ptr that owns the object we are observing. If we |
| 373 | // have expired, the shared_ptr will be empty. We have to be careful |
| 374 | // about concurrency, though, since some other thread might be |
| 375 | // destroying the last owning shared_ptr while we're in this |
| 376 | // function. We want to increment the refcount only if it's nonzero |
| 377 | // and get the new value, and we want that whole operation to be |
| 378 | // atomic. |
| 379 | shared_ptr<T> lock() const { |
| 380 | shared_ptr<T> result; |
| 381 | if (control_block_ != NULL) { |
| 382 | Atomic32 old_refcount; |
| 383 | do { |
| 384 | old_refcount = control_block_->refcount_; |
| 385 | if (old_refcount == 0) |
| 386 | break; |
| 387 | } while (old_refcount != |
| 388 | NoBarrier_CompareAndSwap( |
| 389 | &control_block_->refcount_, old_refcount, |
| 390 | old_refcount + 1)); |
| 391 | if (old_refcount > 0) { |
| 392 | result.ptr_ = ptr_; |
| 393 | result.control_block_ = control_block_; |
| 394 | } |
| 395 | } |
| 396 | |
| 397 | return result; |
| 398 | } |
| 399 | |
| 400 | private: |
| 401 | void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) { |
| 402 | ptr_ = ptr; |
| 403 | control_block_ = control_block; |
| 404 | if (control_block_ != NULL) |
| 405 | RefCountInc(&control_block_->weak_count_); |
| 406 | } |
| 407 | |
| 408 | private: |
| 409 | element_type* ptr_; |
| 410 | SharedPtrControlBlock* control_block_; |
| 411 | }; |
| 412 | |
| 413 | template <typename T> void swap(weak_ptr<T>& r, weak_ptr<T>& s) { |
| 414 | r.swap(s); |
| 415 | } |
| 416 | |
| 417 | // See comments at the top of the file for a description of why this class |
| 418 | // exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009 |
| 419 | // the latest draft is N2914) for the detailed specification. |
| 420 | template <typename T> |
| 421 | class enable_shared_from_this { |
| 422 | friend class shared_ptr<T>; |
| 423 | public: |
| 424 | // Precondition: there must be a shared_ptr that owns *this and that was |
| 425 | // created, directly or indirectly, from a raw pointer of type T*. (The |
| 426 | // latter part of the condition is technical but not quite redundant; it |
| 427 | // rules out some complicated uses involving inheritance hierarchies.) |
| 428 | shared_ptr<T> shared_from_this() { |
| 429 | // Behavior is undefined if the precondition isn't satisfied; we choose |
| 430 | // to die with a CHECK failure. |
| 431 | CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; |
| 432 | return weak_this_.lock(); |
| 433 | } |
| 434 | shared_ptr<const T> shared_from_this() const { |
| 435 | CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; |
| 436 | return weak_this_.lock(); |
| 437 | } |
| 438 | |
| 439 | protected: |
| 440 | enable_shared_from_this() { } |
| 441 | enable_shared_from_this(const enable_shared_from_this& other) { } |
| 442 | enable_shared_from_this& operator=(const enable_shared_from_this& other) { |
| 443 | return *this; |
| 444 | } |
| 445 | ~enable_shared_from_this() { } |
| 446 | |
| 447 | private: |
| 448 | weak_ptr<T> weak_this_; |
| 449 | }; |
| 450 | |
| 451 | // This is a helper function called by shared_ptr's constructor from a raw |
| 452 | // pointer. If T inherits from enable_shared_from_this<T>, it sets up |
| 453 | // weak_this_ so that shared_from_this works correctly. If T does not inherit |
| 454 | // from weak_this we get a different overload, defined inline, which does |
| 455 | // nothing. |
| 456 | template<typename T> |
| 457 | void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) { |
| 458 | if (ptr) { |
| 459 | CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr"; |
| 460 | ptr->weak_this_ = *this; |
| 461 | } |
| 462 | } |
| 463 | |
| 464 | #endif // UTIL_GTL_USE_STD_SHARED_PTR |
| 465 | |
| 466 | } // internal |
| 467 | } // namespace protobuf |
| 468 | } // namespace google |
| 469 | |
| 470 | #endif // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__ |