summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-11 16:58:31 +0000
committerpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-11 16:58:31 +0000
commit5b5ec2d5c5be87a9a7817eeb69dfede4ddf4dd42 (patch)
tree2c593f11ecc91a1749ae388c4326a0a274c82525
parentd7c6a36c9a88244257438698041862888fb397b1 (diff)
downloadchromium_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
-rw-r--r--third_party/protobuf/README.chromium2
-rw-r--r--third_party/protobuf/protobuf.gyp2
-rw-r--r--third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc47
-rw-r--r--third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc60
-rw-r--r--third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h22
-rw-r--r--third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc94
-rw-r--r--third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc12
-rw-r--r--third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc11
-rw-r--r--third_party/protobuf/src/google/protobuf/descriptor.pb.cc62
-rw-r--r--third_party/protobuf/src/google/protobuf/stubs/once.cc79
-rw-r--r--third_party/protobuf/src/google/protobuf/stubs/once.h82
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