Home | History | Annotate | Download | only in stubs
      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__
    471