From 0400cca3236de1ca303af38bf81eab332d042b7c Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Tue, 13 Mar 2018 16:37:29 -0700 Subject: Integrated internal changes from Google --- src/google/protobuf/stubs/callback.h | 15 ++--- src/google/protobuf/stubs/casts.h | 5 +- src/google/protobuf/stubs/common.cc | 80 -------------------------- src/google/protobuf/stubs/common.h | 14 ++++- src/google/protobuf/stubs/io_win32.cc | 8 +-- src/google/protobuf/stubs/io_win32_unittest.cc | 7 +-- src/google/protobuf/stubs/mutex.h | 38 +++++------- src/google/protobuf/stubs/once.h | 71 ++++++----------------- src/google/protobuf/stubs/port.h | 24 +++++++- src/google/protobuf/stubs/singleton.h | 1 - 10 files changed, 84 insertions(+), 179 deletions(-) (limited to 'src/google/protobuf/stubs') diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h index 9ec04979..6888f136 100644 --- a/src/google/protobuf/stubs/callback.h +++ b/src/google/protobuf/stubs/callback.h @@ -1,8 +1,9 @@ #ifndef GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ #define GOOGLE_PROTOBUF_STUBS_CALLBACK_H_ +#include + #include -#include // =================================================================== // emulates google3/base/callback.h @@ -342,7 +343,7 @@ class FunctionResultCallback_1_1 : public ResultCallback1 { template struct InternalConstRef { - typedef typename remove_reference::type base_type; + typedef typename std::remove_reference::type base_type; typedef const base_type& type; }; @@ -397,11 +398,11 @@ class MethodResultCallback_5_2 : public ResultCallback2 { T* object_; MethodType method_; bool self_deleting_; - typename remove_reference::type p1_; - typename remove_reference::type p2_; - typename remove_reference::type p3_; - typename remove_reference::type p4_; - typename remove_reference::type p5_; + typename std::remove_reference::type p1_; + typename std::remove_reference::type p2_; + typename std::remove_reference::type p3_; + typename std::remove_reference::type p4_; + typename std::remove_reference::type p5_; }; } // namespace internal diff --git a/src/google/protobuf/stubs/casts.h b/src/google/protobuf/stubs/casts.h index be652849..35e2dba0 100644 --- a/src/google/protobuf/stubs/casts.h +++ b/src/google/protobuf/stubs/casts.h @@ -31,8 +31,9 @@ #ifndef GOOGLE_PROTOBUF_CASTS_H__ #define GOOGLE_PROTOBUF_CASTS_H__ +#include + #include -#include namespace google { namespace protobuf { @@ -95,7 +96,7 @@ inline To down_cast(From* f) { // so we only accept pointers template // use like this: down_cast(foo); inline To down_cast(From& f) { - typedef typename remove_reference::type* ToAsPointer; + typedef typename std::remove_reference::type* ToAsPointer; // Ensures that To is a sub-type of From *. This test is here only // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index 574c7405..33d24c57 100755 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -313,86 +313,6 @@ namespace internal { FunctionClosure0::~FunctionClosure0() {} } void DoNothing() {} -// =================================================================== -// emulates google3/base/mutex.cc - -#ifdef _WIN32 - -struct Mutex::Internal { - CRITICAL_SECTION mutex; -#ifndef NDEBUG - // Used only to implement AssertHeld(). - DWORD thread_id; -#endif -}; - -Mutex::Mutex() - : mInternal(new Internal) { - InitializeCriticalSection(&mInternal->mutex); -} - -Mutex::~Mutex() { - DeleteCriticalSection(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - EnterCriticalSection(&mInternal->mutex); -#ifndef NDEBUG - mInternal->thread_id = GetCurrentThreadId(); -#endif -} - -void Mutex::Unlock() { -#ifndef NDEBUG - mInternal->thread_id = 0; -#endif - LeaveCriticalSection(&mInternal->mutex); -} - -void Mutex::AssertHeld() { -#ifndef NDEBUG - GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); -#endif -} - -#elif defined(HAVE_PTHREAD) - -struct Mutex::Internal { - pthread_mutex_t mutex; -}; - -Mutex::Mutex() - : mInternal(new Internal) { - pthread_mutex_init(&mInternal->mutex, NULL); -} - -Mutex::~Mutex() { - pthread_mutex_destroy(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - int result = pthread_mutex_lock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); - } -} - -void Mutex::Unlock() { - int result = pthread_mutex_unlock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); - } -} - -void Mutex::AssertHeld() { - // pthreads dosn't provide a way to check which thread holds the mutex. - // TODO(kenton): Maybe keep track of locking thread ID like with WIN32? -} - -#endif - // =================================================================== // emulates google3/util/endian/endian.h // diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 04660b81..2fe8a98b 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,6 @@ // TODO(liujisi): Remove the following includes after the include clean-up. #include -#include #include #include @@ -231,6 +231,18 @@ class FatalException : public std::exception { // in some versions of MSVC. using std::string; +// TODO(gerbens) remove once an extraction cycle has removed all references +namespace internal { +template +using scoped_ptr = std::unique_ptr; +template +using scoped_array = std::unique_ptr; +} // namespace internal +template +using scoped_ptr = std::unique_ptr; +template +using scoped_array = std::unique_ptr; + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/io_win32.cc b/src/google/protobuf/stubs/io_win32.cc index 5ead98c8..4407facb 100644 --- a/src/google/protobuf/stubs/io_win32.cc +++ b/src/google/protobuf/stubs/io_win32.cc @@ -52,13 +52,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include @@ -229,7 +229,7 @@ bool as_windows_path(const char* path, wstring* result) { if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return false; } - scoped_array wcwd(new WCHAR[size]); + std::unique_ptr wcwd(new WCHAR[size]); ::GetCurrentDirectoryW(size, wcwd.get()); wpath = join_paths(wcwd.get(), wpath); } @@ -371,7 +371,7 @@ bool wcs_to_mbs(const WCHAR* s, string* out, bool outUtf8) { || usedDefaultChar) { return false; } - scoped_array astr(new CHAR[size]); + std::unique_ptr astr(new CHAR[size]); WideCharToMultiByte( outUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, astr.get(), size, NULL, NULL); out->assign(astr.get()); @@ -390,7 +390,7 @@ bool mbs_to_wcs(const char* s, wstring* out, bool inUtf8) { if (size == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return false; } - scoped_array wstr(new WCHAR[size]); + std::unique_ptr wstr(new WCHAR[size]); MultiByteToWideChar( inUtf8 ? CP_UTF8 : CP_ACP, 0, s, -1, wstr.get(), size + 1); out->assign(wstr.get()); diff --git a/src/google/protobuf/stubs/io_win32_unittest.cc b/src/google/protobuf/stubs/io_win32_unittest.cc index b216aece..c933757c 100644 --- a/src/google/protobuf/stubs/io_win32_unittest.cc +++ b/src/google/protobuf/stubs/io_win32_unittest.cc @@ -48,7 +48,6 @@ #include #include -#include #include #include @@ -115,7 +114,7 @@ void StripTrailingSlashes(string* str) { bool GetEnvVarAsUtf8(const WCHAR* name, string* result) { DWORD size = ::GetEnvironmentVariableW(name, NULL, 0); if (size > 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) { - scoped_array wcs(new WCHAR[size]); + std::unique_ptr wcs(new WCHAR[size]); ::GetEnvironmentVariableW(name, wcs.get(), size); // GetEnvironmentVariableA retrieves an Active-Code-Page-encoded text which // we'd first need to convert to UTF-16 then to UTF-8, because there seems @@ -131,7 +130,7 @@ bool GetEnvVarAsUtf8(const WCHAR* name, string* result) { bool GetCwdAsUtf8(string* result) { DWORD size = ::GetCurrentDirectoryW(0, NULL); if (size > 0) { - scoped_array wcs(new WCHAR[size]); + std::unique_ptr wcs(new WCHAR[size]); ::GetCurrentDirectoryW(size, wcs.get()); // GetCurrentDirectoryA retrieves an Active-Code-Page-encoded text which // we'd first need to convert to UTF-16 then to UTF-8, because there seems @@ -402,7 +401,7 @@ TEST_F(IoWin32Test, ChdirTestNonAscii) { TEST_F(IoWin32Test, AsWindowsPathTest) { DWORD size = GetCurrentDirectoryW(0, NULL); - scoped_array cwd_str(new wchar_t[size]); + std::unique_ptr cwd_str(new wchar_t[size]); EXPECT_GT(GetCurrentDirectoryW(size, cwd_str.get()), 0); wstring cwd = wstring(L"\\\\?\\") + cwd_str.get(); diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h index 174290f6..b9b7d2e1 100644 --- a/src/google/protobuf/stubs/mutex.h +++ b/src/google/protobuf/stubs/mutex.h @@ -30,9 +30,7 @@ #ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_ #define GOOGLE_PROTOBUF_STUBS_MUTEX_H_ -#ifdef GOOGLE_PROTOBUF_NO_THREADLOCAL -#include -#endif +#include #include @@ -42,34 +40,26 @@ namespace google { namespace protobuf { namespace internal { -// A Mutex is a non-reentrant (aka non-recursive) mutex. At most one thread T -// may hold a mutex at a given time. If T attempts to Lock() the same Mutex -// while holding it, T will deadlock. -class LIBPROTOBUF_EXPORT Mutex { - public: - // Create a Mutex that is not held by anybody. - Mutex(); - - // Destructor - ~Mutex(); - - // Block if necessary until this Mutex is free, then acquire it exclusively. - void Lock(); - - // Release this Mutex. Caller must hold it exclusively. - void Unlock(); +#define GOOGLE_PROTOBUF_LINKER_INITIALIZED +// Mutex is a natural type to wrap. As both google and other organization have +// specialized mutexes. gRPC also provides an injection mechanism for custom +// mutexes. +class LIBPROTOBUF_EXPORT WrappedMutex { + public: + WrappedMutex() = default; + void Lock() { mu_.lock(); } + void Unlock() { mu_.unlock(); } // Crash if this Mutex is not held exclusively by this thread. // May fail to crash when it should; will never crash when it should not. - void AssertHeld(); + void AssertHeld() const {} private: - struct Internal; - Internal* mInternal; - - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); + std::mutex mu_; }; +using Mutex = WrappedMutex; + // MutexLock(mu) acquires mu when constructed and releases it when destroyed. class LIBPROTOBUF_EXPORT MutexLock { public: diff --git a/src/google/protobuf/stubs/once.h b/src/google/protobuf/stubs/once.h index 1f082c37..f3835ccd 100644 --- a/src/google/protobuf/stubs/once.h +++ b/src/google/protobuf/stubs/once.h @@ -78,88 +78,51 @@ #ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__ #define GOOGLE_PROTOBUF_STUBS_ONCE_H__ -#include -#include -#include +#include +#include namespace google { namespace protobuf { +namespace internal { -#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY - -typedef bool ProtobufOnceType; - -#define GOOGLE_PROTOBUF_ONCE_INIT false - -inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { - if (!*once) { - *once = true; - init_func(); - } +using once_flag = std::once_flag; +template +void call_once(Args&&... args ) { + std::call_once(std::forward(args)...); } -template -inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg), - Arg arg) { - if (!*once) { - *once = true; - init_func(arg); - } -} +} // namespace internal -#else - -enum { - ONCE_STATE_UNINITIALIZED = 0, - ONCE_STATE_EXECUTING_CLOSURE = 1, - ONCE_STATE_DONE = 2 -}; - -typedef internal::AtomicWord ProtobufOnceType; - -#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED - -LIBPROTOBUF_EXPORT -void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure); +// TODO(gerbens) remove this once third_party is fully extracted +using ProtobufOnceType = internal::once_flag; inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { - if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { - internal::FunctionClosure0 func(init_func, false); - GoogleOnceInitImpl(once, &func); - } + std::call_once(*once, init_func); } template -inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*), - Arg* arg) { - if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { - internal::FunctionClosure1 func(init_func, false, arg); - GoogleOnceInitImpl(once, &func); - } +inline void GoogleOnceInitArg(ProtobufOnceType* once, void (*init_func)(Arg*), + Arg* arg) { + std::call_once(*once, init_func, arg); } -#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY - class GoogleOnceDynamic { public: - GoogleOnceDynamic() : state_(GOOGLE_PROTOBUF_ONCE_INIT) { } - // If this->Init() has not been called before by any thread, // execute (*func_with_arg)(arg) then return. // Otherwise, wait until that prior invocation has finished // executing its function, then return. template void Init(void (*func_with_arg)(T*), T* arg) { - GoogleOnceInit(&this->state_, - func_with_arg, - arg); + GoogleOnceInitArg(&this->state_, func_with_arg, arg); } private: ProtobufOnceType state_; }; +#define GOOGLE_PROTOBUF_ONCE_TYPE ::google::protobuf::ProtobufOnceType #define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ - ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT + ::google::protobuf::ProtobufOnceType NAME } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 27849298..de83def0 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -93,7 +93,7 @@ #include // NOLINT(build/include) #elif defined(__APPLE__) #include -#elif defined(__GLIBC__) || defined(__CYGWIN__) +#elif defined(__GLIBC__) || defined(__BIONIC__) || defined(__CYGWIN__) #include // IWYU pragma: export #endif @@ -209,6 +209,19 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); #define GOOGLE_PROTOBUF_ATTRIBUTE_NOINLINE GOOGLE_ATTRIBUTE_NOINLINE +#ifndef GOOGLE_ATTRIBUTE_FUNC_ALIGN +#if defined(__clang__) || \ + defined(__GNUC__) && (__GNUC__ > 4 ||(__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +// Function alignment attribute introduced in gcc 4.3 +#define GOOGLE_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__ ((aligned(bytes))) +#else +#define GOOGLE_ATTRIBUTE_FUNC_ALIGN(bytes) +#endif +#endif + +#define GOOGLE_PROTOBUF_ATTRIBUTE_FUNC_ALIGN(bytes) \ + GOOGLE_ATTRIBUTE_FUNC_ALIGN(bytes) + #ifndef GOOGLE_PREDICT_TRUE #ifdef __GNUC__ // Provided at least since GCC 3.0. @@ -227,6 +240,13 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); #endif #endif +#ifndef GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL +#ifdef __GNUC__ +#define GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL \ + __attribute__((returns_nonnull)) +#endif +#endif + // Delimits a block of code which may write to memory which is simultaneously // written by other threads, but which has been determined to be thread-safe // (e.g. because it is an idempotent write). @@ -359,7 +379,7 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) -#elif !defined(__GLIBC__) && !defined(__CYGWIN__) +#elif !defined(__GLIBC__) && !defined(__BIONIC__) && !defined(__CYGWIN__) static inline uint16 bswap_16(uint16 x) { return static_cast(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); diff --git a/src/google/protobuf/stubs/singleton.h b/src/google/protobuf/stubs/singleton.h index 9301f549..2e6ccbdb 100644 --- a/src/google/protobuf/stubs/singleton.h +++ b/src/google/protobuf/stubs/singleton.h @@ -30,7 +30,6 @@ #ifndef GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ #define GOOGLE_PROTOBUF_STUBS_SINGLETON_H__ -#include #include #include -- cgit v1.2.3