Commit de5d4550 authored by Feng Xiao's avatar Feng Xiao

Merge branch 'gerrit' to 'master'

parents 699db2d5 46bd60b9
......@@ -29,6 +29,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arena.h>
#include <google/protobuf/stubs/common.h>
#ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h>
......@@ -43,6 +44,12 @@ Arena::ThreadCache& Arena::thread_cache() {
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL };
return thread_cache_;
}
#elif defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
Arena::ThreadCache& Arena::thread_cache() {
static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
new internal::ThreadLocalStorage<ThreadCache>();
return *thread_cache_->Get();
}
#else
GOOGLE_THREAD_LOCAL Arena::ThreadCache Arena::thread_cache_ = { -1, NULL };
#endif
......
......@@ -373,6 +373,11 @@ class LIBPROTOBUF_EXPORT Arena {
// Thread local variables cannot be exposed through DLL interface but we can
// wrap them in static functions.
static ThreadCache& thread_cache();
#elif defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
// Android ndk does not support __thread keyword so we use a custom thread
// local storage class we implemented.
// iOS also does not support the __thread keyword.
static ThreadCache& thread_cache();
#else
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_;
static ThreadCache& thread_cache() { return thread_cache_; }
......
......@@ -288,6 +288,7 @@ void CommandLineInterfaceTest::Run(const string& command) {
if (!disallow_plugins_) {
cli_.AllowPlugins("prefix-");
#ifndef GOOGLE_THIRD_PARTY_PROTOBUF
const char* possible_paths[] = {
// When building with shared libraries, libtool hides the real executable
// in .libs and puts a fake wrapper in the current directory.
......@@ -316,6 +317,11 @@ void CommandLineInterfaceTest::Run(const string& command) {
}
if (plugin_path.empty()) {
#else
string plugin_path = "third_party/protobuf/test_plugin";
if (access(plugin_path.c_str(), F_OK) != 0) {
#endif // GOOGLE_THIRD_PARTY_PROTOBUF
GOOGLE_LOG(ERROR)
<< "Plugin executable not found. Plugin tests are likely to fail.";
} else {
......
......@@ -1392,6 +1392,12 @@ class OneofTest : public testing::Test {
case unittest::TestOneof2::kFooString:
EXPECT_TRUE(message.has_foo_string());
break;
case unittest::TestOneof2::kFooCord:
EXPECT_TRUE(message.has_foo_cord());
break;
case unittest::TestOneof2::kFooStringPiece:
EXPECT_TRUE(message.has_foo_string_piece());
break;
case unittest::TestOneof2::kFooBytes:
EXPECT_TRUE(message.has_foo_bytes());
break;
......@@ -1404,6 +1410,9 @@ class OneofTest : public testing::Test {
case unittest::TestOneof2::kFoogroup:
EXPECT_TRUE(message.has_foogroup());
break;
case unittest::TestOneof2::kFooLazyMessage:
EXPECT_TRUE(message.has_foo_lazy_message());
break;
case unittest::TestOneof2::FOO_NOT_SET:
break;
}
......
......@@ -59,6 +59,10 @@
#include <vector>
#include <google/protobuf/stubs/common.h>
// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h.
#ifdef TYPE_BOOL
#undef TYPE_BOOL
#endif // TYPE_BOOL
namespace google {
namespace protobuf {
......
......@@ -246,8 +246,6 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) {
protobuf_unittest::TestAllTypes message; // proto2 message
const google::protobuf::Reflection* r = message.GetReflection();
const google::protobuf::Descriptor* d = message.GetDescriptor();
const google::protobuf::FieldDescriptor* singular_field =
d->FindFieldByName("optional_nested_enum");
const google::protobuf::FieldDescriptor* repeated_field =
d->FindFieldByName("repeated_nested_enum");
// Add one element to the repeated field so that we can test
......@@ -258,6 +256,8 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) {
r->AddEnum(&message, repeated_field, enum_value);
#ifdef PROTOBUF_HAS_DEATH_TEST
const google::protobuf::FieldDescriptor* singular_field =
d->FindFieldByName("optional_nested_enum");
// Enum-field integer-based setters GOOGLE_DCHECK-fail on invalid values, in order to
// remain consistent with proto2 generated code.
EXPECT_DEBUG_DEATH({
......
......@@ -626,7 +626,7 @@ DEFINE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(inline, MessageLite);
DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Message);
#undef DECLARE_SPECIALIZATIONS_FOR_BASE_CLASSES
#undef DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES
template <>
inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() {
......
......@@ -33,39 +33,197 @@
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
#include <atomic>
namespace google {
namespace protobuf {
namespace internal {
// This implementation is transitional and maintains the original API for
// atomicops.h. This requires casting memory locations to the atomic types, and
// assumes that the API and the C++11 implementation are layout-compatible,
// which isn't true for all implementations or hardware platforms. The static
// assertion should detect this issue, were it to fire then this header
// shouldn't be used.
//
// TODO(jfb) If this header manages to stay committed then the API should be
// modified, and all call sites updated.
typedef volatile std::atomic<Atomic32>* AtomicLocation32;
static_assert(sizeof(*(AtomicLocation32) nullptr) == sizeof(Atomic32),
"incompatible 32-bit atomic layout");
inline void MemoryBarrier() {
#if defined(__GLIBCXX__)
// Work around libstdc++ bug 51038 where atomic_thread_fence was declared but
// not defined, leading to the linker complaining about undefined references.
__atomic_thread_fence(std::memory_order_seq_cst);
#else
std::atomic_thread_fence(std::memory_order_seq_cst);
#endif
}
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return __sync_val_compare_and_swap(ptr, old_value, new_value);
((AtomicLocation32)ptr)
->compare_exchange_strong(old_value,
new_value,
std::memory_order_relaxed,
std::memory_order_relaxed);
return old_value;
}
inline void MemoryBarrier() {
__sync_synchronize();
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
Atomic32 new_value) {
return ((AtomicLocation32)ptr)
->exchange(new_value, std::memory_order_relaxed);
}
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return increment +
((AtomicLocation32)ptr)
->fetch_add(increment, std::memory_order_relaxed);
}
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return increment + ((AtomicLocation32)ptr)->fetch_add(increment);
}
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
((AtomicLocation32)ptr)
->compare_exchange_strong(old_value,
new_value,
std::memory_order_acquire,
std::memory_order_acquire);
return old_value;
}
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
((AtomicLocation32)ptr)
->compare_exchange_strong(old_value,
new_value,
std::memory_order_release,
std::memory_order_relaxed);
return old_value;
}
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed);
}
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed);
MemoryBarrier();
return ret;
}
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
MemoryBarrier();
*ptr = value;
((AtomicLocation32)ptr)->store(value, std::memory_order_release);
}
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed);
}
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
Atomic32 value = *ptr;
return ((AtomicLocation32)ptr)->load(std::memory_order_acquire);
}
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
MemoryBarrier();
return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed);
}
#if defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
typedef volatile std::atomic<Atomic64>* AtomicLocation64;
static_assert(sizeof(*(AtomicLocation64) nullptr) == sizeof(Atomic64),
"incompatible 64-bit atomic layout");
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
((AtomicLocation64)ptr)
->compare_exchange_strong(old_value,
new_value,
std::memory_order_relaxed,
std::memory_order_relaxed);
return old_value;
}
inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
Atomic64 new_value) {
return ((AtomicLocation64)ptr)
->exchange(new_value, std::memory_order_relaxed);
}
inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return increment +
((AtomicLocation64)ptr)
->fetch_add(increment, std::memory_order_relaxed);
}
inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return increment + ((AtomicLocation64)ptr)->fetch_add(increment);
}
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
((AtomicLocation64)ptr)
->compare_exchange_strong(old_value,
new_value,
std::memory_order_acquire,
std::memory_order_acquire);
return old_value;
}
inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
((AtomicLocation64)ptr)
->compare_exchange_strong(old_value,
new_value,
std::memory_order_release,
std::memory_order_relaxed);
return old_value;
}
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed);
}
inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed);
MemoryBarrier();
return value;
}
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
((AtomicLocation64)ptr)->store(value, std::memory_order_release);
}
inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed);
}
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
return ((AtomicLocation64)ptr)->load(std::memory_order_acquire);
}
inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
MemoryBarrier();
return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed);
}
#endif // defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
} // namespace internal
} // namespace protobuf
} // namespace google
......
......@@ -62,6 +62,14 @@
#include <exception>
#endif
#if defined(__APPLE__)
#include <TargetConditionals.h> // for TARGET_OS_IPHONE
#endif
#if defined(__ANDROID__) || defined(GOOGLE_PROTOBUF_OS_ANDROID) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
#include <pthread.h>
#endif
#if defined(_WIN32) && defined(GetMessage)
// Allow GetMessage to be used as a valid method name in protobuf classes.
// windows.h defines GetMessage() as a macro. Let's re-define it as an inline
......@@ -157,7 +165,7 @@ std::string LIBPROTOBUF_EXPORT VersionString(int version);
typedef unsigned int uint;
#ifdef _MSC_VER
typedef __int8 int8;
typedef signed __int8 int8;
typedef __int16 int16;
typedef __int32 int32;
typedef __int64 int64;
......@@ -1158,6 +1166,38 @@ class LIBPROTOBUF_EXPORT MutexLockMaybe {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe);
};
#if defined(__ANDROID__) || defined(GOOGLE_PROTOBUF_OS_ANDROID) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
// Android ndk does not support the __thread keyword very well yet. Here
// we use pthread_key_create()/pthread_getspecific()/... methods for
// TLS support on android.
// iOS also does not support the __thread keyword.
template<typename T>
class ThreadLocalStorage {
public:
ThreadLocalStorage() {
pthread_key_create(&key_, &ThreadLocalStorage::Delete);
}
~ThreadLocalStorage() {
pthread_key_delete(key_);
}
T* Get() {
T* result = static_cast<T*>(pthread_getspecific(key_));
if (result == NULL) {
result = new T();
pthread_setspecific(key_, result);
}
return result;
}
private:
static void Delete(void* value) {
delete static_cast<T*>(value);
}
pthread_key_t key_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage);
};
#endif
} // namespace internal
// We made these internal so that they would show up as such in the docs,
......
......@@ -172,6 +172,13 @@ struct hash<const char*> {
}
};
template<>
struct hash<bool> {
size_t operator()(bool x) const {
return static_cast<size_t>(x);
}
};
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = std::equal_to<Key>,
......@@ -204,7 +211,7 @@ struct hash<string> {
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
inline size_t operator()(const string& a, const string& b) const {
inline bool operator()(const string& a, const string& b) const {
return a < b;
}
};
......@@ -222,7 +229,7 @@ struct hash<pair<First, Second> > {
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
inline size_t operator()(const pair<First, Second>& a,
inline bool operator()(const pair<First, Second>& a,
const pair<First, Second>& b) const {
return a < b;
}
......
......@@ -95,12 +95,18 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR
#if defined(__APPLE__)
#define GOOGLE_PROTOBUF_OS_APPLE
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define GOOGLE_PROTOBUF_OS_IPHONE
#endif
#elif defined(__native_client__)
#define GOOGLE_PROTOBUF_OS_NACL
#elif defined(sun)
#define GOOGLE_PROTOBUF_OS_SOLARIS
#elif defined(_AIX)
#define GOOGLE_PROTOBUF_OS_AIX
#elif defined(__ANDROID__)
#define GOOGLE_PROTOBUF_OS_ANDROID
#endif
#undef GOOGLE_PROTOBUF_PLATFORM_ERROR
......
......@@ -73,6 +73,10 @@ struct is_base_of {
typedef char (&yes)[1];
typedef char (&no)[2];
// BEGIN GOOGLE LOCAL MODIFICATION -- check is a #define on Mac.
#undef check
// END GOOGLE LOCAL MODIFICATION
static yes check(const B*);
static no check(const void*);
......
......@@ -65,6 +65,7 @@ namespace protobuf {
#endif
string TestSourceDir() {
#ifndef GOOGLE_THIRD_PARTY_PROTOBUF
#ifdef _MSC_VER
// Look for the "src" directory.
string prefix = ".";
......@@ -88,6 +89,9 @@ string TestSourceDir() {
return result;
}
#endif
#else
return "third_party/protobuf/src";
#endif // GOOGLE_THIRD_PARTY_PROTOBUF
}
namespace {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment