From a9abc7831e45257d334cfa682746b6cadf9e95d9 Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Fri, 6 Jul 2018 14:12:33 -0700 Subject: Fix initialization with Visual Studio It appears that Visual Studio does not work well with std::once_flag because it has a bug causing it to initialize that during dynamic initialization instead of constant initialization. This change works around the problem by using function static initializers instead. @gerben-s originally wrote this change for the Google-internal codebase but I am just cherry-picking it here. This fixes #4773. --- src/google/protobuf/extension_set.h | 56 ++++++++++--------------------------- 1 file changed, 14 insertions(+), 42 deletions(-) (limited to 'src/google/protobuf/extension_set.h') diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index c4796629..a1535baa 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -880,18 +880,17 @@ class RepeatedPrimitiveTypeTraits { LIBPROTOBUF_EXPORT extern ProtobufOnceType repeated_primitive_generic_type_traits_once_init_; -class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits { +class LIBPROTOBUF_EXPORT RepeatedPrimitiveDefaults { private: template friend class RepeatedPrimitiveTypeTraits; - static void InitializeDefaultRepeatedFields(); - static void DestroyDefaultRepeatedFields(); - static const RepeatedField* default_repeated_field_int32_; - static const RepeatedField* default_repeated_field_int64_; - static const RepeatedField* default_repeated_field_uint32_; - static const RepeatedField* default_repeated_field_uint64_; - static const RepeatedField* default_repeated_field_double_; - static const RepeatedField* default_repeated_field_float_; - static const RepeatedField* default_repeated_field_bool_; + static const RepeatedPrimitiveDefaults* default_instance(); + RepeatedField default_repeated_field_int32_; + RepeatedField default_repeated_field_int64_; + RepeatedField default_repeated_field_uint32_; + RepeatedField default_repeated_field_uint64_; + RepeatedField default_repeated_field_double_; + RepeatedField default_repeated_field_float_; + RepeatedField default_repeated_field_bool_; }; #define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD) \ @@ -919,11 +918,8 @@ template<> inline void RepeatedPrimitiveTypeTraits::Add( \ } \ template<> inline const RepeatedField* \ RepeatedPrimitiveTypeTraits::GetDefaultRepeatedField() { \ - ::google::protobuf::GoogleOnceInit( \ - &repeated_primitive_generic_type_traits_once_init_, \ - &RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields); \ - return RepeatedPrimitiveGenericTypeTraits:: \ - default_repeated_field_##TYPE##_; \ + return &RepeatedPrimitiveDefaults::default_instance() \ + ->default_repeated_field_##TYPE##_; \ } \ template<> inline const RepeatedField& \ RepeatedPrimitiveTypeTraits::GetRepeated(int number, \ @@ -980,8 +976,6 @@ class LIBPROTOBUF_EXPORT StringTypeTraits { } }; -LIBPROTOBUF_EXPORT extern ProtobufOnceType repeated_string_type_traits_once_init_; - class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { public: typedef const string& ConstType; @@ -1024,11 +1018,7 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { is_packed, NULL)); } - static const RepeatedFieldType* GetDefaultRepeatedField() { - ::google::protobuf::GoogleOnceInit(&repeated_string_type_traits_once_init_, - &InitializeDefaultRepeatedFields); - return default_repeated_field_; - } + static const RepeatedFieldType* GetDefaultRepeatedField(); template static void Register(int number, FieldType type, bool is_packed) { @@ -1039,7 +1029,6 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { private: static void InitializeDefaultRepeatedFields(); static void DestroyDefaultRepeatedFields(); - static const RepeatedFieldType *default_repeated_field_; }; // ------------------------------------------------------------------- @@ -1230,28 +1219,11 @@ class RepeatedMessageTypeTraits { } }; -LIBPROTOBUF_EXPORT extern ProtobufOnceType repeated_message_generic_type_traits_once_init_; - -// This class exists only to hold a generic default empty repeated field for all -// message-type repeated field extensions. -class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits { - public: - typedef RepeatedPtrField<::google::protobuf::MessageLite*> RepeatedFieldType; - private: - template friend class RepeatedMessageTypeTraits; - static void InitializeDefaultRepeatedFields(); - static void DestroyDefaultRepeatedFields(); - static const RepeatedFieldType* default_repeated_field_; -}; - template inline const typename RepeatedMessageTypeTraits::RepeatedFieldType* RepeatedMessageTypeTraits::GetDefaultRepeatedField() { - ::google::protobuf::GoogleOnceInit( - &repeated_message_generic_type_traits_once_init_, - &RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields); - return reinterpret_cast( - RepeatedMessageGenericTypeTraits::default_repeated_field_); + static auto instance = OnShutdownDelete(new RepeatedFieldType); + return instance; } // ------------------------------------------------------------------- -- cgit v1.2.3