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 GOOGLE_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 GOOGLE_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&) { } 442 enable_shared_from_this& operator=(const enable_shared_from_this&) { 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 GOOGLE_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__ 471