From 0977815af285cea479633c6a4017079cb1f2ccac Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Tue, 25 Aug 2015 22:01:12 -0700 Subject: fix "memory leaks" in protostream-object files. Change-Id: I0aca56802d974cb03cb89c1a294f37068b5b9758 --- .../util/internal/protostream_objectsource.cc | 52 ++++++++++-------- .../util/internal/protostream_objectsource.h | 4 +- .../util/internal/protostream_objectwriter.cc | 64 ++++++++++++---------- .../util/internal/protostream_objectwriter.h | 4 +- 4 files changed, 72 insertions(+), 52 deletions(-) (limited to 'src') 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 #include #include +#include #include @@ -648,46 +649,53 @@ Status ProtoStreamObjectSource::RenderFieldMask( } hash_map* -ProtoStreamObjectSource::CreateRendererMap() { - hash_map* result = - new hash_map(); - (*result)["google.protobuf.Timestamp"] = + ProtoStreamObjectSource::renderers_ = NULL; +GOOGLE_PROTOBUF_DECLARE_ONCE(source_renderers_init_); + +void ProtoStreamObjectSource::InitRendererMap() { + renderers_ = new hash_map(); + (*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* 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* CreateRendererMap(); + static hash_map* 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 #include #include +#include #include #include #include @@ -1365,60 +1366,67 @@ void ProtoStreamObjectWriter::RenderSimpleDataPiece( // Map of functions that are responsible for rendering well known type // represented by the key. hash_map* -ProtoStreamObjectWriter::CreateRendererMap() { - google::protobuf::scoped_ptr > - result(new hash_map()); - (*result)["type.googleapis.com/google.protobuf.Timestamp"] = + ProtoStreamObjectWriter::renderers_ = NULL; +GOOGLE_PROTOBUF_DECLARE_ONCE(writer_renderers_init_); + +void ProtoStreamObjectWriter::InitRendererMap() { + renderers_ = new hash_map(); + (*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* 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* CreateRendererMap(); + static hash_map* renderers_; + static void InitRendererMap(); + static void DeleteRendererMap(); static TypeRenderer* FindTypeRenderer(const string& type_url); // Returns the ProtoElement::ElementType for the given Type. -- cgit v1.2.3