aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJisi Liu <liujisi@google.com>2015-08-25 22:05:31 -0700
committerJisi Liu <liujisi@google.com>2015-08-25 22:05:31 -0700
commitf9237d2bcde0e326bcc2fdb88ee0a67d79c9b13c (patch)
treea111cd1dbbaa5c28e89d9ec5c431aa52a8befbb1
parent06c9dfd9a3a6fd18604134c03250734c8d33732d (diff)
parent0977815af285cea479633c6a4017079cb1f2ccac (diff)
downloadprotobuf-f9237d2bcde0e326bcc2fdb88ee0a67d79c9b13c.tar.gz
protobuf-f9237d2bcde0e326bcc2fdb88ee0a67d79c9b13c.tar.bz2
protobuf-f9237d2bcde0e326bcc2fdb88ee0a67d79c9b13c.zip
Merge pull request #741 from pherl/beta-1
fix "memory leaks" in protostream-object files.
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.cc52
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.h4
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.cc64
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.h4
4 files changed, 72 insertions, 52 deletions
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 18bb2772..996e1f8c 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -47,6 +47,7 @@
#include <google/protobuf/util/internal/utility.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/status_macros.h>
@@ -648,46 +649,53 @@ Status ProtoStreamObjectSource::RenderFieldMask(
}
hash_map<string, ProtoStreamObjectSource::TypeRenderer>*
-ProtoStreamObjectSource::CreateRendererMap() {
- hash_map<string, ProtoStreamObjectSource::TypeRenderer>* result =
- new hash_map<string, ProtoStreamObjectSource::TypeRenderer>();
- (*result)["google.protobuf.Timestamp"] =
+ ProtoStreamObjectSource::renderers_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(source_renderers_init_);
+
+void ProtoStreamObjectSource::InitRendererMap() {
+ renderers_ = new hash_map<string, ProtoStreamObjectSource::TypeRenderer>();
+ (*renderers_)["google.protobuf.Timestamp"] =
&ProtoStreamObjectSource::RenderTimestamp;
- (*result)["google.protobuf.Duration"] =
+ (*renderers_)["google.protobuf.Duration"] =
&ProtoStreamObjectSource::RenderDuration;
- (*result)["google.protobuf.DoubleValue"] =
+ (*renderers_)["google.protobuf.DoubleValue"] =
&ProtoStreamObjectSource::RenderDouble;
- (*result)["google.protobuf.FloatValue"] =
+ (*renderers_)["google.protobuf.FloatValue"] =
&ProtoStreamObjectSource::RenderFloat;
- (*result)["google.protobuf.Int64Value"] =
+ (*renderers_)["google.protobuf.Int64Value"] =
&ProtoStreamObjectSource::RenderInt64;
- (*result)["google.protobuf.UInt64Value"] =
+ (*renderers_)["google.protobuf.UInt64Value"] =
&ProtoStreamObjectSource::RenderUInt64;
- (*result)["google.protobuf.Int32Value"] =
+ (*renderers_)["google.protobuf.Int32Value"] =
&ProtoStreamObjectSource::RenderInt32;
- (*result)["google.protobuf.UInt32Value"] =
+ (*renderers_)["google.protobuf.UInt32Value"] =
&ProtoStreamObjectSource::RenderUInt32;
- (*result)["google.protobuf.BoolValue"] = &ProtoStreamObjectSource::RenderBool;
- (*result)["google.protobuf.StringValue"] =
+ (*renderers_)["google.protobuf.BoolValue"] = &ProtoStreamObjectSource::RenderBool;
+ (*renderers_)["google.protobuf.StringValue"] =
&ProtoStreamObjectSource::RenderString;
- (*result)["google.protobuf.BytesValue"] =
+ (*renderers_)["google.protobuf.BytesValue"] =
&ProtoStreamObjectSource::RenderBytes;
- (*result)["google.protobuf.Any"] = &ProtoStreamObjectSource::RenderAny;
- (*result)["google.protobuf.Struct"] = &ProtoStreamObjectSource::RenderStruct;
- (*result)["google.protobuf.Value"] =
+ (*renderers_)["google.protobuf.Any"] = &ProtoStreamObjectSource::RenderAny;
+ (*renderers_)["google.protobuf.Struct"] = &ProtoStreamObjectSource::RenderStruct;
+ (*renderers_)["google.protobuf.Value"] =
&ProtoStreamObjectSource::RenderStructValue;
- (*result)["google.protobuf.ListValue"] =
+ (*renderers_)["google.protobuf.ListValue"] =
&ProtoStreamObjectSource::RenderStructListValue;
- (*result)["google.protobuf.FieldMask"] =
+ (*renderers_)["google.protobuf.FieldMask"] =
&ProtoStreamObjectSource::RenderFieldMask;
- return result;
+ ::google::protobuf::internal::OnShutdown(&DeleteRendererMap);
+}
+
+void ProtoStreamObjectSource::DeleteRendererMap() {
+ delete ProtoStreamObjectSource::renderers_;
+ renderers_ = NULL;
}
// static
ProtoStreamObjectSource::TypeRenderer*
ProtoStreamObjectSource::FindTypeRenderer(const string& type_url) {
- static hash_map<string, TypeRenderer>* renderers = CreateRendererMap();
- return FindOrNull(*renderers, type_url);
+ ::google::protobuf::GoogleOnceInit(&source_renderers_init_, &InitRendererMap);
+ return FindOrNull(*renderers_, type_url);
}
Status ProtoStreamObjectSource::RenderField(
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index 845437f5..f52383a1 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -202,7 +202,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
const google::protobuf::Type& type,
StringPiece name, ObjectWriter* ow);
- static hash_map<string, TypeRenderer>* CreateRendererMap();
+ static hash_map<string, TypeRenderer>* renderers_;
+ static void InitRendererMap();
+ static void DeleteRendererMap();
static TypeRenderer* FindTypeRenderer(const string& type_url);
// Renders a field value to the ObjectWriter.
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 87f504e0..28779301 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/util/internal/object_location_tracker.h>
#include <google/protobuf/util/internal/constants.h>
#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/stubs/statusor.h>
@@ -1365,60 +1366,67 @@ void ProtoStreamObjectWriter::RenderSimpleDataPiece(
// Map of functions that are responsible for rendering well known type
// represented by the key.
hash_map<string, ProtoStreamObjectWriter::TypeRenderer>*
-ProtoStreamObjectWriter::CreateRendererMap() {
- google::protobuf::scoped_ptr<hash_map<string, ProtoStreamObjectWriter::TypeRenderer> >
- result(new hash_map<string, ProtoStreamObjectWriter::TypeRenderer>());
- (*result)["type.googleapis.com/google.protobuf.Timestamp"] =
+ ProtoStreamObjectWriter::renderers_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(writer_renderers_init_);
+
+void ProtoStreamObjectWriter::InitRendererMap() {
+ renderers_ = new hash_map<string, ProtoStreamObjectWriter::TypeRenderer>();
+ (*renderers_)["type.googleapis.com/google.protobuf.Timestamp"] =
&ProtoStreamObjectWriter::RenderTimestamp;
- (*result)["type.googleapis.com/google.protobuf.Duration"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Duration"] =
&ProtoStreamObjectWriter::RenderDuration;
- (*result)["type.googleapis.com/google.protobuf.FieldMask"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.FieldMask"] =
&ProtoStreamObjectWriter::RenderFieldMask;
- (*result)["type.googleapis.com/google.protobuf.Double"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Double"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Float"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Float"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int64"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int64"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt64"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt64"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int32"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int32"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt32"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt32"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Bool"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Bool"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.String"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.String"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Bytes"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Bytes"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.DoubleValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.DoubleValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.FloatValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.FloatValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int64Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int64Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt64Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt64Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int32Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int32Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt32Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt32Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.BoolValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.BoolValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.StringValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.StringValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.BytesValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.BytesValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Value"] =
&ProtoStreamObjectWriter::RenderStructValue;
- return result.release();
+ ::google::protobuf::internal::OnShutdown(&DeleteRendererMap);
+}
+
+void ProtoStreamObjectWriter::DeleteRendererMap() {
+ delete ProtoStreamObjectWriter::renderers_;
+ renderers_ = NULL;
}
ProtoStreamObjectWriter::TypeRenderer*
ProtoStreamObjectWriter::FindTypeRenderer(const string& type_url) {
- static hash_map<string, TypeRenderer>* renderers = CreateRendererMap();
- return FindOrNull(*renderers, type_url);
+ ::google::protobuf::GoogleOnceInit(&writer_renderers_init_, &InitRendererMap);
+ return FindOrNull(*renderers_, type_url);
}
ProtoStreamObjectWriter::ProtoElement::ElementType
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h
index f11c47c0..8f49120b 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.h
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -407,7 +407,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
// Helper functions to create the map and find functions responsible for
// rendering well known types, keyed by type URL.
- static hash_map<string, TypeRenderer>* CreateRendererMap();
+ static hash_map<string, TypeRenderer>* renderers_;
+ static void InitRendererMap();
+ static void DeleteRendererMap();
static TypeRenderer* FindTypeRenderer(const string& type_url);
// Returns the ProtoElement::ElementType for the given Type.