Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
7580a892
Commit
7580a892
authored
Aug 12, 2014
by
jieluo@google.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add shared_pr.h
parent
bde4a325
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
480 additions
and
9 deletions
+480
-9
ez_setup.py
python/ez_setup.py
+0
-1
setup.py
python/setup.py
+10
-8
shared_ptr.h
src/google/protobuf/stubs/shared_ptr.h
+470
-0
No files found.
python/ez_setup.py
View file @
7580a892
...
...
@@ -103,7 +103,6 @@ def use_setuptools(
sys
.
path
.
insert
(
0
,
egg
)
import
setuptools
;
setuptools
.
bootstrap_install_from
=
egg
try
:
return
do_download
()
import
pkg_resources
except
ImportError
:
return
do_download
()
...
...
python/setup.py
View file @
7580a892
...
...
@@ -8,14 +8,17 @@ import subprocess
# We must use setuptools, not distutils, because we need to use the
# namespace_packages option for the "google" package.
try
:
from
ez_setup
import
use_setuptools
use_setuptools
()
from
setuptools
import
setup
,
Extension
,
__version__
from
setuptools
import
setup
,
Extension
except
ImportError
:
sys
.
stderr
.
write
(
"Could not import setuptools; make sure you have setuptools or "
"ez_setup installed.
\n
"
)
raise
try
:
from
ez_setup
import
use_setuptools
use_setuptools
()
from
setuptools
import
setup
,
Extension
except
ImportError
:
sys
.
stderr
.
write
(
"Could not import setuptools; make sure you have setuptools or "
"ez_setup installed.
\n
"
)
raise
from
distutils.command.clean
import
clean
as
_clean
from
distutils.command.build_py
import
build_py
as
_build_py
from
distutils.spawn
import
find_executable
...
...
@@ -118,7 +121,6 @@ class build_py(_build_py):
if
__name__
==
'__main__'
:
print
(
__version__
)
# C++ implementation extension
nocpp
=
'--nocpp_implementation'
if
nocpp
in
sys
.
argv
:
...
...
src/google/protobuf/stubs/shared_ptr.h
0 → 100644
View file @
7580a892
// Protocol Buffers - Google's data interchange format
// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// from google3/util/gtl/shared_ptr.h
#ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
#define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
#include <google/protobuf/stubs/atomicops.h>
#include <algorithm> // for swap
#include <stddef.h>
#include <memory>
namespace
google
{
namespace
protobuf
{
namespace
internal
{
// Alias to std::shared_ptr for any C++11 platform,
// and for any supported MSVC compiler.
#if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \
(defined(COMPILER_MSVC) || defined(LANG_CXX11))
#define UTIL_GTL_USE_STD_SHARED_PTR 1
#endif
#if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR
// These are transitional. They will be going away soon.
// Please just #include <memory> and just type std::shared_ptr yourself, instead
// of relying on this file.
//
// Migration doc: http://go/std-shared-ptr-lsc
using
std
::
enable_shared_from_this
;
using
std
::
shared_ptr
;
using
std
::
static_pointer_cast
;
using
std
::
weak_ptr
;
#else // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0.
// For everything else there is the google3 implementation.
inline
bool
RefCountDec
(
volatile
Atomic32
*
ptr
)
{
return
Barrier_AtomicIncrement
(
ptr
,
-
1
)
!=
0
;
}
inline
void
RefCountInc
(
volatile
Atomic32
*
ptr
)
{
NoBarrier_AtomicIncrement
(
ptr
,
1
);
}
template
<
typename
T
>
class
shared_ptr
;
template
<
typename
T
>
class
weak_ptr
;
// This class is an internal implementation detail for shared_ptr. If two
// shared_ptrs point to the same object, they also share a control block.
// An "empty" shared_pointer refers to NULL and also has a NULL control block.
// It contains all of the state that's needed for reference counting or any
// other kind of resource management. In this implementation the control block
// happens to consist of two atomic words, the reference count (the number
// of shared_ptrs that share ownership of the object) and the weak count
// (the number of weak_ptrs that observe the object, plus 1 if the
// refcount is nonzero).
//
// The "plus 1" is to prevent a race condition in the shared_ptr and
// weak_ptr destructors. We need to make sure the control block is
// only deleted once, so we need to make sure that at most one
// object sees the weak count decremented from 1 to 0.
class
SharedPtrControlBlock
{
template
<
typename
T
>
friend
class
shared_ptr
;
template
<
typename
T
>
friend
class
weak_ptr
;
private
:
SharedPtrControlBlock
()
:
refcount_
(
1
),
weak_count_
(
1
)
{
}
Atomic32
refcount_
;
Atomic32
weak_count_
;
};
// Forward declaration. The class is defined below.
template
<
typename
T
>
class
enable_shared_from_this
;
template
<
typename
T
>
class
shared_ptr
{
template
<
typename
U
>
friend
class
weak_ptr
;
public
:
typedef
T
element_type
;
shared_ptr
()
:
ptr_
(
NULL
),
control_block_
(
NULL
)
{}
explicit
shared_ptr
(
T
*
ptr
)
:
ptr_
(
ptr
),
control_block_
(
ptr
!=
NULL
?
new
SharedPtrControlBlock
:
NULL
)
{
// If p is non-null and T inherits from enable_shared_from_this, we
// set up the data that shared_from_this needs.
MaybeSetupWeakThis
(
ptr
);
}
// Copy constructor: makes this object a copy of ptr, and increments
// the reference count.
template
<
typename
U
>
shared_ptr
(
const
shared_ptr
<
U
>&
ptr
)
:
ptr_
(
NULL
),
control_block_
(
NULL
)
{
Initialize
(
ptr
);
}
// Need non-templated version to prevent the compiler-generated default
shared_ptr
(
const
shared_ptr
<
T
>&
ptr
)
:
ptr_
(
NULL
),
control_block_
(
NULL
)
{
Initialize
(
ptr
);
}
// Assignment operator. Replaces the existing shared_ptr with ptr.
// Increment ptr's reference count and decrement the one being replaced.
template
<
typename
U
>
shared_ptr
<
T
>&
operator
=
(
const
shared_ptr
<
U
>&
ptr
)
{
if
(
ptr_
!=
ptr
.
ptr_
)
{
shared_ptr
<
T
>
me
(
ptr
);
// will hold our previous state to be destroyed.
swap
(
me
);
}
return
*
this
;
}
// Need non-templated version to prevent the compiler-generated default
shared_ptr
<
T
>&
operator
=
(
const
shared_ptr
<
T
>&
ptr
)
{
if
(
ptr_
!=
ptr
.
ptr_
)
{
shared_ptr
<
T
>
me
(
ptr
);
// will hold our previous state to be destroyed.
swap
(
me
);
}
return
*
this
;
}
// TODO(austern): Consider providing this constructor. The draft C++ standard
// (20.8.10.2.1) includes it. However, it says that this constructor throws
// a bad_weak_ptr exception when ptr is expired. Is it better to provide this
// constructor and make it do something else, like fail with a CHECK, or to
// leave this constructor out entirely?
//
// template <typename U>
// shared_ptr(const weak_ptr<U>& ptr);
~
shared_ptr
()
{
if
(
ptr_
!=
NULL
)
{
if
(
!
RefCountDec
(
&
control_block_
->
refcount_
))
{
delete
ptr_
;
// weak_count_ is defined as the number of weak_ptrs that observe
// ptr_, plus 1 if refcount_ is nonzero.
if
(
!
RefCountDec
(
&
control_block_
->
weak_count_
))
{
delete
control_block_
;
}
}
}
}
// Replaces underlying raw pointer with the one passed in. The reference
// count is set to one (or zero if the pointer is NULL) for the pointer
// being passed in and decremented for the one being replaced.
//
// If you have a compilation error with this code, make sure you aren't
// passing NULL, nullptr, or 0 to this function. Call reset without an
// argument to reset to a null ptr.
template
<
typename
Y
>
void
reset
(
Y
*
p
)
{
if
(
p
!=
ptr_
)
{
shared_ptr
<
T
>
tmp
(
p
);
tmp
.
swap
(
*
this
);
}
}
void
reset
()
{
reset
(
static_cast
<
T
*>
(
NULL
));
}
// Exchanges the contents of this with the contents of r. This function
// supports more efficient swapping since it eliminates the need for a
// temporary shared_ptr object.
void
swap
(
shared_ptr
<
T
>&
r
)
{
using
std
::
swap
;
// http://go/using-std-swap
swap
(
ptr_
,
r
.
ptr_
);
swap
(
control_block_
,
r
.
control_block_
);
}
// The following function is useful for gaining access to the underlying
// pointer when a shared_ptr remains in scope so the reference-count is
// known to be > 0 (e.g. for parameter passing).
T
*
get
()
const
{
return
ptr_
;
}
T
&
operator
*
()
const
{
return
*
ptr_
;
}
T
*
operator
->
()
const
{
return
ptr_
;
}
long
use_count
()
const
{
return
control_block_
?
control_block_
->
refcount_
:
1
;
}
bool
unique
()
const
{
return
use_count
()
==
1
;
}
private
:
// If r is non-empty, initialize *this to share ownership with r,
// increasing the underlying reference count.
// If r is empty, *this remains empty.
// Requires: this is empty, namely this->ptr_ == NULL.
template
<
typename
U
>
void
Initialize
(
const
shared_ptr
<
U
>&
r
)
{
// This performs a static_cast on r.ptr_ to U*, which is a no-op since it
// is already a U*. So initialization here requires that r.ptr_ is
// implicitly convertible to T*.
InitializeWithStaticCast
<
U
>
(
r
);
}
// Initializes *this as described in Initialize, but additionally performs a
// static_cast from r.ptr_ (V*) to U*.
// NOTE(gfc): We'd need a more general form to support const_pointer_cast and
// dynamic_pointer_cast, but those operations are sufficiently discouraged
// that supporting static_pointer_cast is sufficient.
template
<
typename
U
,
typename
V
>
void
InitializeWithStaticCast
(
const
shared_ptr
<
V
>&
r
)
{
if
(
r
.
control_block_
!=
NULL
)
{
RefCountInc
(
&
r
.
control_block_
->
refcount_
);
ptr_
=
static_cast
<
U
*>
(
r
.
ptr_
);
control_block_
=
r
.
control_block_
;
}
}
// Helper function for the constructor that takes a raw pointer. If T
// doesn't inherit from enable_shared_from_this<T> then we have nothing to
// do, so this function is trivial and inline. The other version is declared
// out of line, after the class definition of enable_shared_from_this.
void
MaybeSetupWeakThis
(
enable_shared_from_this
<
T
>*
ptr
);
void
MaybeSetupWeakThis
(...)
{
}
T
*
ptr_
;
SharedPtrControlBlock
*
control_block_
;
#ifndef SWIG
template
<
typename
U
>
friend
class
shared_ptr
;
template
<
typename
U
,
typename
V
>
friend
shared_ptr
<
U
>
static_pointer_cast
(
const
shared_ptr
<
V
>&
rhs
);
#endif
};
// Matches the interface of std::swap as an aid to generic programming.
template
<
typename
T
>
void
swap
(
shared_ptr
<
T
>&
r
,
shared_ptr
<
T
>&
s
)
{
r
.
swap
(
s
);
}
template
<
typename
T
,
typename
U
>
shared_ptr
<
T
>
static_pointer_cast
(
const
shared_ptr
<
U
>&
rhs
)
{
shared_ptr
<
T
>
lhs
;
lhs
.
template
InitializeWithStaticCast
<
T
>
(
rhs
);
return
lhs
;
}
// See comments at the top of the file for a description of why this
// class exists, and the draft C++ standard (as of July 2009 the
// latest draft is N2914) for the detailed specification.
template
<
typename
T
>
class
weak_ptr
{
template
<
typename
U
>
friend
class
weak_ptr
;
public
:
typedef
T
element_type
;
// Create an empty (i.e. already expired) weak_ptr.
weak_ptr
()
:
ptr_
(
NULL
),
control_block_
(
NULL
)
{
}
// Create a weak_ptr that observes the same object that ptr points
// to. Note that there is no race condition here: we know that the
// control block can't disappear while we're looking at it because
// it is owned by at least one shared_ptr, ptr.
template
<
typename
U
>
weak_ptr
(
const
shared_ptr
<
U
>&
ptr
)
{
CopyFrom
(
ptr
.
ptr_
,
ptr
.
control_block_
);
}
// Copy a weak_ptr. The object it points to might disappear, but we
// don't care: we're only working with the control block, and it can't
// disappear while we're looking at because it's owned by at least one
// weak_ptr, ptr.
template
<
typename
U
>
weak_ptr
(
const
weak_ptr
<
U
>&
ptr
)
{
CopyFrom
(
ptr
.
ptr_
,
ptr
.
control_block_
);
}
// Need non-templated version to prevent default copy constructor
weak_ptr
(
const
weak_ptr
&
ptr
)
{
CopyFrom
(
ptr
.
ptr_
,
ptr
.
control_block_
);
}
// Destroy the weak_ptr. If no shared_ptr owns the control block, and if
// we are the last weak_ptr to own it, then it can be deleted. Note that
// weak_count_ is defined as the number of weak_ptrs sharing this control
// block, plus 1 if there are any shared_ptrs. We therefore know that it's
// safe to delete the control block when weak_count_ reaches 0, without
// having to perform any additional tests.
~
weak_ptr
()
{
if
(
control_block_
!=
NULL
&&
!
RefCountDec
(
&
control_block_
->
weak_count_
))
{
delete
control_block_
;
}
}
weak_ptr
&
operator
=
(
const
weak_ptr
&
ptr
)
{
if
(
&
ptr
!=
this
)
{
weak_ptr
tmp
(
ptr
);
tmp
.
swap
(
*
this
);
}
return
*
this
;
}
template
<
typename
U
>
weak_ptr
&
operator
=
(
const
weak_ptr
<
U
>&
ptr
)
{
weak_ptr
tmp
(
ptr
);
tmp
.
swap
(
*
this
);
return
*
this
;
}
template
<
typename
U
>
weak_ptr
&
operator
=
(
const
shared_ptr
<
U
>&
ptr
)
{
weak_ptr
tmp
(
ptr
);
tmp
.
swap
(
*
this
);
return
*
this
;
}
void
swap
(
weak_ptr
&
ptr
)
{
using
std
::
swap
;
// http://go/using-std-swap
swap
(
ptr_
,
ptr
.
ptr_
);
swap
(
control_block_
,
ptr
.
control_block_
);
}
void
reset
()
{
weak_ptr
tmp
;
tmp
.
swap
(
*
this
);
}
// Return the number of shared_ptrs that own the object we are observing.
// Note that this number can be 0 (if this pointer has expired).
long
use_count
()
const
{
return
control_block_
!=
NULL
?
control_block_
->
refcount_
:
0
;
}
bool
expired
()
const
{
return
use_count
()
==
0
;
}
// Return a shared_ptr that owns the object we are observing. If we
// have expired, the shared_ptr will be empty. We have to be careful
// about concurrency, though, since some other thread might be
// destroying the last owning shared_ptr while we're in this
// function. We want to increment the refcount only if it's nonzero
// and get the new value, and we want that whole operation to be
// atomic.
shared_ptr
<
T
>
lock
()
const
{
shared_ptr
<
T
>
result
;
if
(
control_block_
!=
NULL
)
{
Atomic32
old_refcount
;
do
{
old_refcount
=
control_block_
->
refcount_
;
if
(
old_refcount
==
0
)
break
;
}
while
(
old_refcount
!=
NoBarrier_CompareAndSwap
(
&
control_block_
->
refcount_
,
old_refcount
,
old_refcount
+
1
));
if
(
old_refcount
>
0
)
{
result
.
ptr_
=
ptr_
;
result
.
control_block_
=
control_block_
;
}
}
return
result
;
}
private
:
void
CopyFrom
(
T
*
ptr
,
SharedPtrControlBlock
*
control_block
)
{
ptr_
=
ptr
;
control_block_
=
control_block
;
if
(
control_block_
!=
NULL
)
RefCountInc
(
&
control_block_
->
weak_count_
);
}
private
:
element_type
*
ptr_
;
SharedPtrControlBlock
*
control_block_
;
};
template
<
typename
T
>
void
swap
(
weak_ptr
<
T
>&
r
,
weak_ptr
<
T
>&
s
)
{
r
.
swap
(
s
);
}
// See comments at the top of the file for a description of why this class
// exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009
// the latest draft is N2914) for the detailed specification.
template
<
typename
T
>
class
enable_shared_from_this
{
friend
class
shared_ptr
<
T
>
;
public
:
// Precondition: there must be a shared_ptr that owns *this and that was
// created, directly or indirectly, from a raw pointer of type T*. (The
// latter part of the condition is technical but not quite redundant; it
// rules out some complicated uses involving inheritance hierarchies.)
shared_ptr
<
T
>
shared_from_this
()
{
// Behavior is undefined if the precondition isn't satisfied; we choose
// to die with a CHECK failure.
CHECK
(
!
weak_this_
.
expired
())
<<
"No shared_ptr owns this object"
;
return
weak_this_
.
lock
();
}
shared_ptr
<
const
T
>
shared_from_this
()
const
{
CHECK
(
!
weak_this_
.
expired
())
<<
"No shared_ptr owns this object"
;
return
weak_this_
.
lock
();
}
protected
:
enable_shared_from_this
()
{
}
enable_shared_from_this
(
const
enable_shared_from_this
&
other
)
{
}
enable_shared_from_this
&
operator
=
(
const
enable_shared_from_this
&
other
)
{
return
*
this
;
}
~
enable_shared_from_this
()
{
}
private
:
weak_ptr
<
T
>
weak_this_
;
};
// This is a helper function called by shared_ptr's constructor from a raw
// pointer. If T inherits from enable_shared_from_this<T>, it sets up
// weak_this_ so that shared_from_this works correctly. If T does not inherit
// from weak_this we get a different overload, defined inline, which does
// nothing.
template
<
typename
T
>
void
shared_ptr
<
T
>::
MaybeSetupWeakThis
(
enable_shared_from_this
<
T
>*
ptr
)
{
if
(
ptr
)
{
CHECK
(
ptr
->
weak_this_
.
expired
())
<<
"Object already owned by a shared_ptr"
;
ptr
->
weak_this_
=
*
this
;
}
}
#endif // UTIL_GTL_USE_STD_SHARED_PTR
}
// internal
}
// namespace protobuf
}
// namespace google
#endif // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment