diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 35b1c92..9e21635 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -89,27 +89,17 @@ static void InitWeakDefaults() { void InitWeakDefaults() {} #endif -PROTOBUF_CONSTINIT std::atomic init_protobuf_defaults_state{false}; -static bool InitProtobufDefaultsImpl() { - if (auto* to_destroy = fixed_address_empty_string.Init()) { - OnShutdownDestroyString(to_destroy); - } - InitWeakDefaults(); - - - init_protobuf_defaults_state.store(true, std::memory_order_release); - return true; -} - +PROTOBUF_CONSTINIT bool init_protobuf_defaults_state{false}; void InitProtobufDefaultsSlow() { - static bool is_inited = InitProtobufDefaultsImpl(); - (void)is_inited; + fixed_address_empty_string.Init(); + init_protobuf_defaults_state = true; + InitWeakDefaults(); } // Force the initialization of the empty string. // Normally, registration would do it, but we don't have any guarantee that // there is any object with reflection. PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 static std::true_type init_empty_string = - (InitProtobufDefaultsSlow(), std::true_type{}); + (InitProtobufDefaults(), std::true_type{}); const std::string& GetEmptyString() { InitProtobufDefaults(); diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 6b64840..771b45d 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -71,11 +71,14 @@ class ExtensionSet; // This fastpath inlines a single branch instead of having to make the // InitProtobufDefaults function call. // It also generates less inlined code than a function-scope static initializer. -PROTOBUF_EXPORT extern std::atomic init_protobuf_defaults_state; +PROTOBUF_EXPORT extern bool init_protobuf_defaults_state; PROTOBUF_EXPORT void InitProtobufDefaultsSlow(); PROTOBUF_EXPORT inline void InitProtobufDefaults() { - if (ABSL_PREDICT_FALSE( - !init_protobuf_defaults_state.load(std::memory_order_acquire))) { + // This is not thread-safe, but is called within a static initializer. As long + // as there are no calls to this function from off the main thread, before + // main() starts, this is safe. After main() starts, + // init_protobuf_defaults_state will always be true. + if (ABSL_PREDICT_FALSE(!init_protobuf_defaults_state)) { InitProtobufDefaultsSlow(); } } diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 1cd73d2..3c7c91f 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -555,15 +555,7 @@ #define PROTOBUF_FINAL final #endif -// Determines the platforms where descriptor weak messages can be used. -#ifdef PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED -#error PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED was previously defined -#endif -#if defined(__GNUC__) && defined(__clang__) && !defined(__APPLE__) && \ - !defined(_MSC_VER) && !defined(_WIN32) && !defined(__wasm__) && \ - !defined(__EMSCRIPTEN__) -#define PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED -#endif + // TODO: Enable the feature by default and remove this flag. #ifdef PROTOBUF_PREFETCH_PARSE_TABLE