diff options
author | pliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 16:58:31 +0000 |
---|---|---|
committer | pliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-11 16:58:31 +0000 |
commit | 5b5ec2d5c5be87a9a7817eeb69dfede4ddf4dd42 (patch) | |
tree | 2c593f11ecc91a1749ae388c4326a0a274c82525 | |
parent | d7c6a36c9a88244257438698041862888fb397b1 (diff) | |
download | chromium_src-5b5ec2d5c5be87a9a7817eeb69dfede4ddf4dd42.zip chromium_src-5b5ec2d5c5be87a9a7817eeb69dfede4ddf4dd42.tar.gz chromium_src-5b5ec2d5c5be87a9a7817eeb69dfede4ddf4dd42.tar.bz2 |
third_party/protobuf: update to upstream r415.
1) Got an upstream diff 412:415 from svn
2) Applied and fixed conflicts in cpp_message.cc
3) Added -DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER in protobuf.gyp
Note that this removes 52 static initializers previously generated by protoc.
Review URL: https://chromiumcodereview.appspot.com/10382099
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136585 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 347 insertions, 126 deletions
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium index df9f1c0..c421f17 100644 --- a/third_party/protobuf/README.chromium +++ b/third_party/protobuf/README.chromium @@ -3,7 +3,7 @@ Short Name: protobuf URL: http://protobuf.googlecode.com/svn/trunk License File: COPYING.txt Version: unknown -Revision: r412 +Revision: r415 Security Critical: yes Local files (not taken from upstream): diff --git a/third_party/protobuf/protobuf.gyp b/third_party/protobuf/protobuf.gyp index a0ab85a..4385785 100644 --- a/third_party/protobuf/protobuf.gyp +++ b/third_party/protobuf/protobuf.gyp @@ -87,6 +87,7 @@ # which requires RTTI. 'defines': [ 'GOOGLE_PROTOBUF_NO_RTTI', + 'GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER', ], 'direct_dependent_settings': { @@ -96,6 +97,7 @@ ], 'defines': [ 'GOOGLE_PROTOBUF_NO_RTTI', + 'GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER', ], }, }, diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc index 810600b..3e6d414 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -386,11 +386,12 @@ void FileGenerator::GenerateSource(io::Printer* printer) { void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // AddDescriptors() is a file-level procedure which adds the encoded - // FileDescriptorProto for this .proto file to the global DescriptorPool - // for generated files (DescriptorPool::generated_pool()). It always runs - // at static initialization time, so all files will be registered before - // main() starts. This procedure also constructs default instances and - // registers extensions. + // FileDescriptorProto for this .proto file to the global DescriptorPool for + // generated files (DescriptorPool::generated_pool()). It either runs at + // static initialization time (by default) or when default_instance() is + // called for the first time (in LITE_RUNTIME mode with + // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also + // constructs default instances and registers extensions. // // Its sibling, AssignDescriptors(), actually pulls the compiled // FileDescriptor from the DescriptorPool and uses it to populate all of @@ -494,22 +495,27 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { printer->Outdent(); printer->Print( - "}\n"); + "}\n\n"); // ----------------------------------------------------------------- // Now generate the AddDescriptors() function. - printer->Print( - "\n" + PrintHandlingOptionalStaticInitializers( + file_, printer, + // With static initializers. + // Note that we don't need any special synchronization in the following code + // because it is called at static init time before any threads exist. "void $adddescriptorsname$() {\n" - // We don't need any special synchronization here because this code is - // called at static init time before any threads exist. " static bool already_here = false;\n" " if (already_here) return;\n" " already_here = true;\n" - " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" - "\n", + " GOOGLE_PROTOBUF_VERIFY_VERSION;\n", + // Without. + "void $adddescriptorsname$_impl() {\n" + " GOOGLE_PROTOBUF_VERIFY_VERSION;\n", + // Vars. "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); + printer->Indent(); // Call the AddDescriptors() methods for all of our dependencies, to make @@ -577,17 +583,26 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "shutdownfilename", GlobalShutdownFileName(file_->name())); printer->Outdent(); - printer->Print( "}\n" - "\n" + "\n"); + + PrintHandlingOptionalStaticInitializers( + file_, printer, + // With static initializers. "// Force AddDescriptors() to be called at static initialization time.\n" "struct StaticDescriptorInitializer_$filename$ {\n" " StaticDescriptorInitializer_$filename$() {\n" " $adddescriptorsname$();\n" " }\n" - "} static_descriptor_initializer_$filename$_;\n" - "\n", + "} static_descriptor_initializer_$filename$_;\n", + // Without. + "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n" + "void $adddescriptorsname$() {\n" + " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n" + " &$adddescriptorsname$_impl);\n" + "}\n", + // Vars. "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), "filename", FilenameIdentifier(file_->name())); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 25b05a8..c4b868c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -33,10 +33,12 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include <limits> +#include <map> #include <vector> #include <google/protobuf/stubs/hash.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> +#include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> @@ -105,6 +107,20 @@ string UnderscoresToCamelCase(const string& input, bool cap_next_letter) { return result; } +// Returns whether the provided descriptor has an extension. This includes its +// nested types. +bool HasExtension(const Descriptor* descriptor) { + if (descriptor->extension_count() > 0) { + return true; + } + for (int i = 0; i < descriptor->nested_type_count(); ++i) { + if (HasExtension(descriptor->nested_type(i))) { + return true; + } + } + return false; +} + } // namespace const char kThickSeparator[] = @@ -341,6 +357,50 @@ string EscapeTrigraphs(const string& to_escape) { return StringReplace(to_escape, "?", "\\?", true); } +bool StaticInitializersForced(const FileDescriptor* file) { + if (HasDescriptorMethods(file) || file->extension_count() > 0) { + return true; + } + for (int i = 0; i < file->message_type_count(); ++i) { + if (HasExtension(file->message_type(i))) { + return true; + } + } + return false; +} + +void PrintHandlingOptionalStaticInitializers( + const FileDescriptor* file, io::Printer* printer, + const char* with_static_init, const char* without_static_init, + const char* var1, const string& val1, + const char* var2, const string& val2) { + map<string, string> vars; + if (var1) { + vars[var1] = val1; + } + if (var2) { + vars[var2] = val2; + } + PrintHandlingOptionalStaticInitializers( + vars, file, printer, with_static_init, without_static_init); +} + +void PrintHandlingOptionalStaticInitializers( + const map<string, string>& vars, const FileDescriptor* file, + io::Printer* printer, const char* with_static_init, + const char* without_static_init) { + if (StaticInitializersForced(file)) { + printer->Print(vars, with_static_init); + } else { + printer->Print(vars, (string( + "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n") + + without_static_init + + "#else\n" + + with_static_init + + "#endif\n").c_str()); + } +} + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h index ac06398..690fbec 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -35,12 +35,18 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ +#include <map> #include <string> #include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor.pb.h> namespace google { namespace protobuf { + +namespace io { +class Printer; +} + namespace compiler { namespace cpp { @@ -151,6 +157,22 @@ inline bool HasFastArraySerialization(const FileDescriptor* file) { return file->options().optimize_for() == FileOptions::SPEED; } +// Returns whether we have to generate code with static initializers. +bool StaticInitializersForced(const FileDescriptor* file); + +// Prints 'with_static_init' if static initializers have to be used for the +// provided file. Otherwise emits both 'with_static_init' and +// 'without_static_init' using #ifdef. +void PrintHandlingOptionalStaticInitializers( + const FileDescriptor* file, io::Printer* printer, + const char* with_static_init, const char* without_static_init, + const char* var1 = NULL, const string& val1 = "", + const char* var2 = NULL, const string& val2 = ""); + +void PrintHandlingOptionalStaticInitializers( + const map<string, string>& vars, const FileDescriptor* file, + io::Printer* printer, const char* with_static_init, + const char* without_static_init); } // namespace cpp } // namespace compiler diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc index b836fb6..4248747 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -493,6 +493,19 @@ GenerateClassDefinition(io::Printer* printer) { "static const $classname$& default_instance();\n" "\n"); + if (!StaticInitializersForced(descriptor_->file())) { + printer->Print(vars, + "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" + "// Returns the internal default instance pointer. This function can\n" + "// return NULL thus should not be used by the user. This is intended\n" + "// for Protobuf internal code. Please use default_instance() declared\n" + "// above instead.\n" + "static inline const $classname$* internal_default_instance() {\n" + " return default_instance_;\n" + "}\n" + "#endif\n" + "\n"); + } printer->Print(vars, "void Swap($classname$* other);\n" @@ -660,11 +673,17 @@ GenerateClassDefinition(io::Printer* printer) { // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as // friends so that they can access private static variables like // default_instance_ and reflection_. - printer->Print( + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. "friend void $dllexport_decl$ $adddescriptorsname$();\n", + // Without. + "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n", + // Vars. "dllexport_decl", dllexport_decl_, "adddescriptorsname", - GlobalAddDescriptorsName(descriptor_->file()->name())); + GlobalAddDescriptorsName(descriptor_->file()->name())); + printer->Print( "friend void $assigndescriptorsname$();\n" "friend void $shutdownfilename$();\n" @@ -981,8 +1000,12 @@ GenerateSharedDestructorCode(io::Printer* printer) { .GenerateDestructorCode(printer); } - printer->Print( - "if (this != default_instance_) {\n"); + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + "if (this != default_instance_) {\n", + // Without. + "if (this != &default_instance()) {\n"); // We need to delete all embedded messages. // TODO(kenton): If we make unset messages point at default instances @@ -1034,10 +1057,16 @@ GenerateStructors(io::Printer* printer) { if (!field->is_repeated() && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - printer->Print( - " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", - "name", FieldName(field), - "type", FieldMessageTypeName(field)); + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", + // Without. + " $name$_ = const_cast< $type$*>(\n" + " $type$::internal_default_instance());\n", + // Vars. + "name", FieldName(field), + "type", FieldMessageTypeName(field)); } } printer->Print( @@ -1093,8 +1122,20 @@ GenerateStructors(io::Printer* printer) { } printer->Print( - "const $classname$& $classname$::default_instance() {\n" - " if (default_instance_ == NULL) $adddescriptorsname$();" + "const $classname$& $classname$::default_instance() {\n", + "classname", classname_); + + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " if (default_instance_ == NULL) $adddescriptorsname$();\n", + // Without. + " $adddescriptorsname$();\n", + // Vars. + "adddescriptorsname", + GlobalAddDescriptorsName(descriptor_->file()->name())); + + printer->Print( " return *default_instance_;\n" "}\n" "\n" @@ -1106,7 +1147,6 @@ GenerateStructors(io::Printer* printer) { "classname", classname_, "adddescriptorsname", GlobalAddDescriptorsName(descriptor_->file()->name())); - } void MessageGenerator:: @@ -1377,11 +1417,22 @@ GenerateMergeFromCodedStream(io::Printer* printer) { // Special-case MessageSet. printer->Print( "bool $classname$::MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input) {\n" + " ::google::protobuf::io::CodedInputStream* input) {\n", + "classname", classname_); + + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. " return _extensions_.ParseMessageSet(input, default_instance_,\n" - " mutable_unknown_fields());\n" - "}\n", + " mutable_unknown_fields());\n", + // Without. + " return _extensions_.ParseMessageSet(input, &default_instance(),\n" + " mutable_unknown_fields());\n", + // Vars. "classname", classname_); + + printer->Print( + "}\n"); return; } @@ -1541,12 +1592,21 @@ GenerateMergeFromCodedStream(io::Printer* printer) { } printer->Print(") {\n"); if (HasUnknownFields(descriptor_->file())) { - printer->Print( + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. " DO_(_extensions_.ParseField(tag, input, default_instance_,\n" + " mutable_unknown_fields()));\n", + // Without. + " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n" " mutable_unknown_fields()));\n"); } else { - printer->Print( - " DO_(_extensions_.ParseField(tag, input, default_instance_, NULL));\n"); + PrintHandlingOptionalStaticInitializers( + descriptor_->file(), printer, + // With static initializers. + " DO_(_extensions_.ParseField(tag, input, default_instance_, NULL));\n", + // Without. + " DO_(_extensions_.ParseField(tag, input, &default_instance(), NULL));\n"); } printer->Print( " continue;\n" diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 23e75b8..7c785e7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -82,8 +82,16 @@ GenerateAccessorDeclarations(io::Printer* printer) const { void MessageFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer) const { printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" - " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n" + "inline const $type$& $classname$::$name$() const {\n"); + + PrintHandlingOptionalStaticInitializers( + variables_, descriptor_->file(), printer, + // With static initializers. + " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n", + // Without. + " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n"); + + printer->Print(variables_, "}\n" "inline $type$* $classname$::mutable_$name$() {\n" " set_has_$name$();\n" diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc index 75b5ffb..1d27b41 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc @@ -124,7 +124,6 @@ void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { if (already_here) return; already_here = true; GOOGLE_PROTOBUF_VERIFY_VERSION; - ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n%google/protobuf/compiler/plugin.proto\022" @@ -155,7 +154,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto } } static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_; - // =================================================================== #ifndef _MSC_VER @@ -207,7 +205,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() { } const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + return *default_instance_; } CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL; @@ -529,7 +528,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() { } const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + return *default_instance_; } CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL; @@ -857,7 +857,8 @@ const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() { } const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + return *default_instance_; } CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL; diff --git a/third_party/protobuf/src/google/protobuf/descriptor.pb.cc b/third_party/protobuf/src/google/protobuf/descriptor.pb.cc index 468b433..47595bb 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor.pb.cc +++ b/third_party/protobuf/src/google/protobuf/descriptor.pb.cc @@ -554,7 +554,6 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { if (already_here) return; already_here = true; GOOGLE_PROTOBUF_VERIFY_VERSION; - ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n google/protobuf/descriptor.proto\022\017goog" "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file" @@ -708,7 +707,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto { } } static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_; - // =================================================================== #ifndef _MSC_VER @@ -754,7 +752,8 @@ const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() { } const FileDescriptorSet& FileDescriptorSet::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL; @@ -980,7 +979,8 @@ const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() { } const FileDescriptorProto& FileDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL; @@ -1559,7 +1559,8 @@ const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor } const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL; @@ -1815,7 +1816,8 @@ const ::google::protobuf::Descriptor* DescriptorProto::descriptor() { } const DescriptorProto& DescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } DescriptorProto* DescriptorProto::default_instance_ = NULL; @@ -2390,7 +2392,8 @@ const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() { } const FieldDescriptorProto& FieldDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL; @@ -2944,7 +2947,8 @@ const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() { } const EnumDescriptorProto& EnumDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL; @@ -3259,7 +3263,8 @@ const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() { } const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL; @@ -3569,7 +3574,8 @@ const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() { } const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL; @@ -3892,7 +3898,8 @@ const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() { } const MethodDescriptorProto& MethodDescriptorProto::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL; @@ -4306,7 +4313,8 @@ const ::google::protobuf::Descriptor* FileOptions::descriptor() { } const FileOptions& FileOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } FileOptions* FileOptions::default_instance_ = NULL; @@ -4908,7 +4916,8 @@ const ::google::protobuf::Descriptor* MessageOptions::descriptor() { } const MessageOptions& MessageOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } MessageOptions* MessageOptions::default_instance_ = NULL; @@ -5242,7 +5251,8 @@ const ::google::protobuf::Descriptor* FieldOptions::descriptor() { } const FieldOptions& FieldOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } FieldOptions* FieldOptions::default_instance_ = NULL; @@ -5638,7 +5648,8 @@ const ::google::protobuf::Descriptor* EnumOptions::descriptor() { } const EnumOptions& EnumOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } EnumOptions* EnumOptions::default_instance_ = NULL; @@ -5861,7 +5872,8 @@ const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() { } const EnumValueOptions& EnumValueOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } EnumValueOptions* EnumValueOptions::default_instance_ = NULL; @@ -6084,7 +6096,8 @@ const ::google::protobuf::Descriptor* ServiceOptions::descriptor() { } const ServiceOptions& ServiceOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } ServiceOptions* ServiceOptions::default_instance_ = NULL; @@ -6307,7 +6320,8 @@ const ::google::protobuf::Descriptor* MethodOptions::descriptor() { } const MethodOptions& MethodOptions::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } MethodOptions* MethodOptions::default_instance_ = NULL; @@ -6536,7 +6550,8 @@ const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() } const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL; @@ -6813,7 +6828,8 @@ const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() { } const UninterpretedOption& UninterpretedOption::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } UninterpretedOption* UninterpretedOption::default_instance_ = NULL; @@ -7283,7 +7299,8 @@ const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() { } const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL; @@ -7570,7 +7587,8 @@ const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() { } const SourceCodeInfo& SourceCodeInfo::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; } SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL; diff --git a/third_party/protobuf/src/google/protobuf/stubs/once.cc b/third_party/protobuf/src/google/protobuf/stubs/once.cc index 5b7af9c..1e24b85 100644 --- a/third_party/protobuf/src/google/protobuf/stubs/once.cc +++ b/third_party/protobuf/src/google/protobuf/stubs/once.cc @@ -35,54 +35,65 @@ // This header is intended to be included only by internal .cc files and // generated .pb.cc files. Users should not use this directly. +#include <google/protobuf/stubs/once.h> + +#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY + #ifdef _WIN32 #include <windows.h> +#else +#include <sched.h> #endif -#include <google/protobuf/stubs/once.h> +#include <google/protobuf/stubs/atomicops.h> namespace google { namespace protobuf { -#ifdef _WIN32 - -struct ProtobufOnceInternal { - ProtobufOnceInternal() { - InitializeCriticalSection(&critical_section); - } - ~ProtobufOnceInternal() { - DeleteCriticalSection(&critical_section); - } - CRITICAL_SECTION critical_section; -}; - -ProtobufOnceType::~ProtobufOnceType() -{ - delete internal_; - internal_ = NULL; -} +namespace { -ProtobufOnceType::ProtobufOnceType() { - // internal_ may be non-NULL if Init() was already called. - if (internal_ == NULL) internal_ = new ProtobufOnceInternal; +void SchedYield() { +#ifdef _WIN32 + Sleep(0); +#else // POSIX + sched_yield(); +#endif } -void ProtobufOnceType::Init(void (*init_func)()) { - // internal_ may be NULL if we're still in dynamic initialization and the - // constructor has not been called yet. As mentioned in once.h, we assume - // that the program is still single-threaded at this time, and therefore it - // should be safe to initialize internal_ like so. - if (internal_ == NULL) internal_ = new ProtobufOnceInternal; +} // namespace - EnterCriticalSection(&internal_->critical_section); - if (!initialized_) { - init_func(); - initialized_ = true; +void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) { + internal::AtomicWord state = internal::Acquire_Load(once); + // Fast path. The provided closure was already executed. + if (state == ONCE_STATE_DONE) { + return; + } + // The closure execution did not complete yet. The once object can be in one + // of the two following states: + // - UNINITIALIZED: We are the first thread calling this function. + // - EXECUTING_CLOSURE: Another thread is already executing the closure. + // + // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE + // atomically. + state = internal::Acquire_CompareAndSwap( + once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE); + if (state == ONCE_STATE_UNINITIALIZED) { + // We are the first thread to call this function, so we have to call the + // closure. + closure->Run(); + internal::Release_Store(once, ONCE_STATE_DONE); + } else { + // Another thread has already started executing the closure. We need to + // wait until it completes the initialization. + while (state == ONCE_STATE_EXECUTING_CLOSURE) { + // Note that futex() could be used here on Linux as an improvement. + SchedYield(); + state = internal::Acquire_Load(once); + } } - LeaveCriticalSection(&internal_->critical_section); } -#endif - } // namespace protobuf } // namespace google + +#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY diff --git a/third_party/protobuf/src/google/protobuf/stubs/once.h b/third_party/protobuf/src/google/protobuf/stubs/once.h index 0dee407..c8cbe24 100644 --- a/third_party/protobuf/src/google/protobuf/stubs/once.h +++ b/third_party/protobuf/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,68 @@ #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)()); - - volatile bool initialized_; - ProtobufOnceInternal* internal_; -}; +typedef bool ProtobufOnceType; -#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 +}; -#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ - pthread_once_t NAME = PTHREAD_ONCE_INIT +typedef internal::AtomicWord ProtobufOnceType; + +#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED + +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); + } } -#endif +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 // GOOGLE_PROTOBUF_NO_THREAD_SAFETY + +#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \ + ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT } // namespace protobuf } // namespace google |