diff options
Diffstat (limited to 'src/google/protobuf/stubs/once.h')
-rw-r--r-- | src/google/protobuf/stubs/once.h | 71 |
1 files changed, 17 insertions, 54 deletions
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 <google/protobuf/stubs/atomicops.h> -#include <google/protobuf/stubs/callback.h> -#include <google/protobuf/stubs/common.h> +#include <mutex> +#include <utility> 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 <typename... Args> +void call_once(Args&&... args ) { + std::call_once(std::forward<Args>(args)...); } -template <typename Arg> -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 <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); - } +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<typename T> void Init(void (*func_with_arg)(T*), T* arg) { - GoogleOnceInit<T>(&this->state_, - func_with_arg, - arg); + GoogleOnceInitArg<T>(&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 |