diff options
author | Jeff Davidson <jpd@google.com> | 2014-09-15 16:29:06 -0700 |
---|---|---|
committer | Jeff Davidson <jpd@google.com> | 2015-01-15 14:10:53 -0800 |
commit | a3b2a6da25a76f17c73d31def3952feb0fd2296e (patch) | |
tree | 586f7d5e9a7e05af45d0e821188097c0faa96219 /src/google/protobuf/stubs/once.h | |
parent | c7c25812eb19d080087b71e08bfe35aff9f21433 (diff) | |
download | external_protobuf-a3b2a6da25a76f17c73d31def3952feb0fd2296e.zip external_protobuf-a3b2a6da25a76f17c73d31def3952feb0fd2296e.tar.gz external_protobuf-a3b2a6da25a76f17c73d31def3952feb0fd2296e.tar.bz2 |
Update protobuf library from 2.3 to 2.6.
Copied in all files from the open source protobuf project at commit
edc5994525c79cd1919859a370837a6ff7c8e308, removing files which have
been renamed (COPYING.txt -> LICENSE, README.txt -> README.md).
Removed 2.3 prebuilts, which is an approach that will not work due to
incompatibility with the 2.6 runtime.
Merged in micro/nano-specific changes in the following files:
-Android.mk - updated list of C++/Java sources, bumped versions
-java/README.txt - merged in micro/nano instructions, bumped versions
-java/pom.xml - merged in micro/nano build rules, set packaging to jar
-src/Makefile.am - merged in references to micro/nano generators
-src/google/protobuf/compiler/javamicro/javamicro_file.h - imported
google/protobuf/compiler/code_generator.h and removed redundant
OutputDirectory class.
-src/google/protobuf/compiler/javanano/javanano_file.h - same
-Replaced instances of vector with std::vector as needed to get
libprotobuf-cpp-full to compile. Plan to upstream this fix per
discussion with protobuf maintainers.
Reran autogen.sh to update ./configure and associated scripts.
Change-Id: I949d32fb5126f1c05e2a6ed48f6636a4a9b15a48
Diffstat (limited to 'src/google/protobuf/stubs/once.h')
-rw-r--r-- | src/google/protobuf/stubs/once.h | 101 |
1 files changed, 72 insertions, 29 deletions
diff --git a/src/google/protobuf/stubs/once.h b/src/google/protobuf/stubs/once.h index 0dee407..86a4c01 100644 --- a/src/google/protobuf/stubs/once.h +++ b/src/google/protobuf/stubs/once.h @@ -37,16 +37,22 @@ // // This is basically a portable version of pthread_once(). // -// This header declares three things: +// This header declares: // * A type called ProtobufOnceType. // * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type // ProtobufOnceType. This is the only legal way to declare such a variable. -// The macro may only be used at the global scope (you cannot create local -// or class member variables of this type). -// * A function GogoleOnceInit(ProtobufOnceType* once, void (*init_func)()). +// The macro may only be used at the global scope (you cannot create local or +// class member variables of this type). +// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()). // This function, when invoked multiple times given the same ProtobufOnceType // object, will invoke init_func on the first call only, and will make sure // none of the calls return before that first call to init_func has finished. +// * The user can provide a parameter which GoogleOnceInit() forwards to the +// user-provided function when it is called. Usage example: +// int a = 10; +// GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a); +// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no +// static initializer generated). // // This implements a way to perform lazy initialization. It's more efficient // than using mutexes as no lock is needed if initialization has already @@ -72,50 +78,87 @@ #ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__ #define GOOGLE_PROTOBUF_STUBS_ONCE_H__ +#include <google/protobuf/stubs/atomicops.h> #include <google/protobuf/stubs/common.h> -#ifndef _WIN32 -#include <pthread.h> -#endif - namespace google { namespace protobuf { -#ifdef _WIN32 - -struct ProtobufOnceInternal; +#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY -struct LIBPROTOBUF_EXPORT ProtobufOnceType { - ProtobufOnceType(); - ~ProtobufOnceType(); - void Init(void (*init_func)()); +typedef bool ProtobufOnceType; - volatile bool initialized_; - ProtobufOnceInternal* internal_; -}; - -#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ - ::google::protobuf::ProtobufOnceType NAME +#define GOOGLE_PROTOBUF_ONCE_INIT false inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { - // Note: Double-checked locking is safe on x86. - if (!once->initialized_) { - once->Init(init_func); + if (!*once) { + *once = true; + init_func(); + } +} + +template <typename Arg> +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg), + Arg arg) { + if (!*once) { + *once = true; + init_func(arg); } } #else -typedef pthread_once_t ProtobufOnceType; +enum { + ONCE_STATE_UNINITIALIZED = 0, + ONCE_STATE_EXECUTING_CLOSURE = 1, + ONCE_STATE_DONE = 2 +}; + +typedef internal::AtomicWord ProtobufOnceType; -#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ - pthread_once_t NAME = PTHREAD_ONCE_INIT +#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED + +LIBPROTOBUF_EXPORT +void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure); inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) { - pthread_once(once, init_func); + if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { + internal::FunctionClosure0 func(init_func, false); + GoogleOnceInitImpl(once, &func); + } +} + +template <typename Arg> +inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*), + Arg* arg) { + if (internal::Acquire_Load(once) != ONCE_STATE_DONE) { + internal::FunctionClosure1<Arg*> func(init_func, false, arg); + GoogleOnceInitImpl(once, &func); + } } -#endif +#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<typename T> + void Init(void (*func_with_arg)(T*), T* arg) { + GoogleOnceInit<T>(&this->state_, + func_with_arg, + arg); + } + private: + ProtobufOnceType state_; +}; + +#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ + ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT } // namespace protobuf } // namespace google |