blob: d250bf4d33850d0a48507d10d1bcfd181cc2d853 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// 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
42namespace google {
43namespace protobuf {
44namespace 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
60using std::enable_shared_from_this;
61using std::shared_ptr;
62using std::static_pointer_cast;
63using 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.
68inline bool RefCountDec(volatile Atomic32 *ptr) {
69 return Barrier_AtomicIncrement(ptr, -1) != 0;
70}
71
72inline void RefCountInc(volatile Atomic32 *ptr) {
73 NoBarrier_AtomicIncrement(ptr, 1);
74}
75
76template <typename T> class shared_ptr;
77template <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.
93class 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.
103template <typename T> class enable_shared_from_this;
104
105template <typename T>
106class 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.
278template <typename T> void swap(shared_ptr<T>& r, shared_ptr<T>& s) {
279 r.swap(s);
280}
281
282template <typename T, typename U>
283shared_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.
292template <typename T>
293class 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
413template <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.
420template <typename T>
421class 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.
456template<typename T>
457void 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__