Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
63e646b7
Commit
63e646b7
authored
May 06, 2009
by
kenton@google.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Provide ShutdownProtobufLibrary() which frees all startup-allocated objects.
parent
9824eda6
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
254 additions
and
43 deletions
+254
-43
cpp_file.cc
src/google/protobuf/compiler/cpp/cpp_file.cc
+29
-5
cpp_helpers.cc
src/google/protobuf/compiler/cpp/cpp_helpers.cc
+5
-0
cpp_helpers.h
src/google/protobuf/compiler/cpp/cpp_helpers.h
+3
-0
cpp_message.cc
src/google/protobuf/compiler/cpp/cpp_message.cc
+20
-4
cpp_message.h
src/google/protobuf/compiler/cpp/cpp_message.h
+4
-0
descriptor.cc
src/google/protobuf/descriptor.cc
+16
-11
descriptor.pb.cc
src/google/protobuf/descriptor.pb.cc
+40
-0
descriptor.pb.h
src/google/protobuf/descriptor.pb.h
+19
-0
extension_set.cc
src/google/protobuf/extension_set.cc
+12
-1
common.cc
src/google/protobuf/stubs/common.cc
+67
-22
common.h
src/google/protobuf/stubs/common.h
+25
-0
googletest.cc
src/google/protobuf/testing/googletest.cc
+14
-0
No files found.
src/google/protobuf/compiler/cpp/cpp_file.cc
View file @
63e646b7
...
...
@@ -143,20 +143,23 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
// Open namespace.
GenerateNamespaceOpeners
(
printer
);
// Forward-declare the AddDescriptors
and AssignDescriptors functions, so
// that we can declare them to be friends of each class.
// Forward-declare the AddDescriptors
, AssignDescriptors, and ShutdownFile
//
functions, so
that we can declare them to be friends of each class.
printer
->
Print
(
"
\n
"
"// Internal implementation detail -- do not call these.
\n
"
"void $dllexport_decl$ $adddescriptorsname$();
\n
"
,
"adddescriptorsname"
,
GlobalAddDescriptorsName
(
file_
->
name
()),
"dllexport_decl"
,
dllexport_decl_
);
printer
->
Print
(
// Note that we don't put dllexport_decl on th
is because it is only called
//
by the .pb.cc file in which it is
defined.
// Note that we don't put dllexport_decl on th
ese because they are only
//
called by the .pb.cc file in which they are
defined.
"void $assigndescriptorsname$();
\n
"
"void $shutdownfilename$();
\n
"
"
\n
"
,
"assigndescriptorsname"
,
GlobalAssignDescriptorsName
(
file_
->
name
()));
"assigndescriptorsname"
,
GlobalAssignDescriptorsName
(
file_
->
name
()),
"shutdownfilename"
,
GlobalShutdownFileName
(
file_
->
name
()));
// Generate forward declarations of classes.
for
(
int
i
=
0
;
i
<
file_
->
message_type_count
();
i
++
)
{
...
...
@@ -390,6 +393,23 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// -----------------------------------------------------------------
// ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown.
printer
->
Print
(
"
\n
"
"void $shutdownfilename$() {
\n
"
,
"shutdownfilename"
,
GlobalShutdownFileName
(
file_
->
name
()));
printer
->
Indent
();
for
(
int
i
=
0
;
i
<
file_
->
message_type_count
();
i
++
)
{
message_generators_
[
i
]
->
GenerateShutdownCode
(
printer
);
}
printer
->
Outdent
();
printer
->
Print
(
"}
\n
"
);
// -----------------------------------------------------------------
// Now generate the AddDescriptors() function.
printer
->
Print
(
"
\n
"
...
...
@@ -462,6 +482,10 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
message_generators_
[
i
]
->
GenerateDefaultInstanceInitializer
(
printer
);
}
printer
->
Print
(
"::google::protobuf::internal::OnShutdown(&$shutdownfilename$);
\n
"
,
"shutdownfilename"
,
GlobalShutdownFileName
(
file_
->
name
()));
printer
->
Outdent
();
printer
->
Print
(
...
...
src/google/protobuf/compiler/cpp/cpp_helpers.cc
View file @
63e646b7
...
...
@@ -276,6 +276,11 @@ string GlobalAssignDescriptorsName(const string& filename) {
return
"protobuf_AssignDesc_"
+
FilenameIdentifier
(
filename
);
}
// Return the name of the ShutdownFile() function for a given file.
string
GlobalShutdownFileName
(
const
string
&
filename
)
{
return
"protobuf_ShutdownFile_"
+
FilenameIdentifier
(
filename
);
}
}
// namespace cpp
}
// namespace compiler
}
// namespace protobuf
...
...
src/google/protobuf/compiler/cpp/cpp_helpers.h
View file @
63e646b7
...
...
@@ -102,6 +102,9 @@ string GlobalAddDescriptorsName(const string& filename);
// Return the name of the AssignDescriptors() function for a given file.
string
GlobalAssignDescriptorsName
(
const
string
&
filename
);
// Return the name of the ShutdownFile() function for a given file.
string
GlobalShutdownFileName
(
const
string
&
filename
);
}
// namespace cpp
}
// namespace compiler
}
// namespace protobuf
...
...
src/google/protobuf/compiler/cpp/cpp_message.cc
View file @
63e646b7
...
...
@@ -421,17 +421,20 @@ GenerateClassDefinition(io::Printer* printer) {
.
GeneratePrivateMembers
(
printer
);
}
// Declare AddDescriptors() and BuildDescriptors() as friends so that they
// can assign private static variables like default_instance_ and reflection_.
// Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
// friends so that they can access private static variables like
// default_instance_ and reflection_.
printer
->
Print
(
"friend void $dllexport_decl$ $adddescriptorsname$();
\n
"
,
"dllexport_decl"
,
dllexport_decl_
,
"adddescriptorsname"
,
GlobalAddDescriptorsName
(
descriptor_
->
file
()
->
name
()));
printer
->
Print
(
"friend void $assigndescriptorsname$();
\n
"
,
"friend void $assigndescriptorsname$();
\n
"
"friend void $shutdownfilename$();
\n
"
,
"assigndescriptorsname"
,
GlobalAssignDescriptorsName
(
descriptor_
->
file
()
->
name
()));
GlobalAssignDescriptorsName
(
descriptor_
->
file
()
->
name
()),
"shutdownfilename"
,
GlobalShutdownFileName
(
descriptor_
->
file
()
->
name
()));
// Generate offsets and _has_bits_ boilerplate.
if
(
descriptor_
->
field_count
()
>
0
)
{
...
...
@@ -599,6 +602,19 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) {
}
}
void
MessageGenerator
::
GenerateShutdownCode
(
io
::
Printer
*
printer
)
{
printer
->
Print
(
"delete $classname$::default_instance_;
\n
"
"delete $classname$_reflection_;
\n
"
,
"classname"
,
classname_
);
// Handle nested types.
for
(
int
i
=
0
;
i
<
descriptor_
->
nested_type_count
();
i
++
)
{
nested_generators_
[
i
]
->
GenerateShutdownCode
(
printer
);
}
}
void
MessageGenerator
::
GenerateClassMethods
(
io
::
Printer
*
printer
)
{
for
(
int
i
=
0
;
i
<
descriptor_
->
enum_type_count
();
i
++
)
{
...
...
src/google/protobuf/compiler/cpp/cpp_message.h
View file @
63e646b7
...
...
@@ -98,6 +98,10 @@ class MessageGenerator {
// allocated before any can be initialized.
void
GenerateDefaultInstanceInitializer
(
io
::
Printer
*
printer
);
// Generates code that should be run when ShutdownProtobufLibrary() is called,
// to delete all dynamically-allocated objects.
void
GenerateShutdownCode
(
io
::
Printer
*
printer
);
// Generate all non-inline methods for this class.
void
GenerateClassMethods
(
io
::
Printer
*
printer
);
...
...
src/google/protobuf/descriptor.cc
View file @
63e646b7
...
...
@@ -47,6 +47,7 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/map-util.h>
...
...
@@ -797,30 +798,34 @@ namespace {
EncodedDescriptorDatabase
*
generated_database_
=
NULL
;
DescriptorPool
*
generated_pool_
=
NULL
;
GOOGLE_PROTOBUF_DECLARE_ONCE
(
generated_pool_init_
);
void
DeleteGeneratedPool
()
{
delete
generated_database_
;
generated_database_
=
NULL
;
delete
generated_pool_
;
generated_pool_
=
NULL
;
}
void
InitGeneratedPool
()
{
GOOGLE_CHECK
(
generated_pool_
==
NULL
);
generated_database_
=
new
EncodedDescriptorDatabase
;
generated_pool_
=
new
DescriptorPool
(
generated_database_
);
internal
::
OnShutdown
(
&
DeleteGeneratedPool
);
}
// Force InitGeneratedPool to be called at static init time, before any threads
// can be created.
struct
Initializer
{
Initializer
()
{
if
(
generated_pool_
==
NULL
)
InitGeneratedPool
();
}
}
initializer
;
inline
void
InitGeneratedPoolOnce
()
{
GoogleOnceInit
(
&
generated_pool_init_
,
&
InitGeneratedPool
);
}
}
// anonymous namespace
const
DescriptorPool
*
DescriptorPool
::
generated_pool
()
{
if
(
generated_pool_
==
NULL
)
InitGeneratedPool
();
InitGeneratedPoolOnce
();
return
generated_pool_
;
}
DescriptorPool
*
DescriptorPool
::
internal_generated_pool
()
{
if
(
generated_pool_
==
NULL
)
InitGeneratedPool
();
InitGeneratedPoolOnce
();
return
generated_pool_
;
}
...
...
@@ -848,7 +853,7 @@ void DescriptorPool::InternalAddGeneratedFile(
// Therefore, when we parse one, we have to be very careful to avoid using
// any descriptor-based operations, since this might cause infinite recursion
// or deadlock.
if
(
generated_pool_
==
NULL
)
InitGeneratedPool
();
InitGeneratedPoolOnce
();
GOOGLE_CHECK
(
generated_database_
->
Add
(
encoded_file_descriptor
,
size
));
}
...
...
src/google/protobuf/descriptor.pb.cc
View file @
63e646b7
...
...
@@ -451,6 +451,45 @@ void protobuf_RegisterTypes() {
}
// namespace
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
()
{
delete
FileDescriptorSet
::
default_instance_
;
delete
FileDescriptorSet_reflection_
;
delete
FileDescriptorProto
::
default_instance_
;
delete
FileDescriptorProto_reflection_
;
delete
DescriptorProto
::
default_instance_
;
delete
DescriptorProto_reflection_
;
delete
DescriptorProto_ExtensionRange
::
default_instance_
;
delete
DescriptorProto_ExtensionRange_reflection_
;
delete
FieldDescriptorProto
::
default_instance_
;
delete
FieldDescriptorProto_reflection_
;
delete
EnumDescriptorProto
::
default_instance_
;
delete
EnumDescriptorProto_reflection_
;
delete
EnumValueDescriptorProto
::
default_instance_
;
delete
EnumValueDescriptorProto_reflection_
;
delete
ServiceDescriptorProto
::
default_instance_
;
delete
ServiceDescriptorProto_reflection_
;
delete
MethodDescriptorProto
::
default_instance_
;
delete
MethodDescriptorProto_reflection_
;
delete
FileOptions
::
default_instance_
;
delete
FileOptions_reflection_
;
delete
MessageOptions
::
default_instance_
;
delete
MessageOptions_reflection_
;
delete
FieldOptions
::
default_instance_
;
delete
FieldOptions_reflection_
;
delete
EnumOptions
::
default_instance_
;
delete
EnumOptions_reflection_
;
delete
EnumValueOptions
::
default_instance_
;
delete
EnumValueOptions_reflection_
;
delete
ServiceOptions
::
default_instance_
;
delete
ServiceOptions_reflection_
;
delete
MethodOptions
::
default_instance_
;
delete
MethodOptions_reflection_
;
delete
UninterpretedOption
::
default_instance_
;
delete
UninterpretedOption_reflection_
;
delete
UninterpretedOption_NamePart
::
default_instance_
;
delete
UninterpretedOption_NamePart_reflection_
;
}
void
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
()
{
static
bool
already_here
=
false
;
if
(
already_here
)
return
;
...
...
@@ -584,6 +623,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
MethodOptions
::
default_instance_
->
InitAsDefaultInstance
();
UninterpretedOption
::
default_instance_
->
InitAsDefaultInstance
();
UninterpretedOption_NamePart
::
default_instance_
->
InitAsDefaultInstance
();
::
google
::
protobuf
::
internal
::
OnShutdown
(
&
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
);
}
// Force AddDescriptors() to be called at static initialization time.
...
...
src/google/protobuf/descriptor.pb.h
View file @
63e646b7
...
...
@@ -28,6 +28,7 @@ namespace protobuf {
// Internal implementation detail -- do not call these.
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
class
FileDescriptorSet
;
class
FileDescriptorProto
;
...
...
@@ -210,6 +211,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
FileDescriptorProto
>
file_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
1
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -381,6 +383,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
::
google
::
protobuf
::
FileOptions
*
options_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
8
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -475,6 +478,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto
::
google
::
protobuf
::
int32
end_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
2
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -630,6 +634,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
::
google
::
protobuf
::
MessageOptions
*
options_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
7
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -849,6 +854,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa
::
google
::
protobuf
::
FieldOptions
*
options_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
8
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -958,6 +964,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
::
google
::
protobuf
::
EnumOptions
*
options_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
3
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1064,6 +1071,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M
::
google
::
protobuf
::
EnumValueOptions
*
options_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
3
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1173,6 +1181,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
::
google
::
protobuf
::
ServiceOptions
*
options_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
3
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1295,6 +1304,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess
::
google
::
protobuf
::
MethodOptions
*
options_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
4
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1448,6 +1458,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
UninterpretedOption
>
uninterpreted_option_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
5
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1547,6 +1558,7 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
UninterpretedOption
>
uninterpreted_option_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
2
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1696,6 +1708,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
UninterpretedOption
>
uninterpreted_option_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
5
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1787,6 +1800,7 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
UninterpretedOption
>
uninterpreted_option_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
1
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1878,6 +1892,7 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
UninterpretedOption
>
uninterpreted_option_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
1
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -1969,6 +1984,7 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
UninterpretedOption
>
uninterpreted_option_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
1
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -2060,6 +2076,7 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
::
google
::
protobuf
::
RepeatedPtrField
<
::
google
::
protobuf
::
UninterpretedOption
>
uninterpreted_option_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
1
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -2158,6 +2175,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu
bool
is_extension_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
2
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
@@ -2297,6 +2315,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
static
const
::
std
::
string
_default_string_value_
;
friend
void
LIBPROTOBUF_EXPORT
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto
();
friend
void
protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto
();
::
google
::
protobuf
::
uint32
_has_bits_
[(
6
+
31
)
/
32
];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
...
...
src/google/protobuf/extension_set.cc
View file @
63e646b7
...
...
@@ -78,11 +78,22 @@ struct ExtensionInfo {
typedef
hash_map
<
pair
<
const
Message
*
,
int
>
,
ExtensionInfo
>
ExtensionRegistry
;
ExtensionRegistry
*
registry_
=
NULL
;
GOOGLE_PROTOBUF_DECLARE_ONCE
(
registry_init_
);
void
DeleteRegistry
()
{
delete
registry_
;
registry_
=
NULL
;
}
void
InitRegistry
()
{
registry_
=
new
ExtensionRegistry
;
internal
::
OnShutdown
(
&
DeleteRegistry
);
}
// This function is only called at startup, so there is no need for thread-
// safety.
void
Register
(
const
Message
*
containing_type
,
int
number
,
ExtensionInfo
info
)
{
if
(
registry_
==
NULL
)
registry_
=
new
ExtensionRegistry
;
GoogleOnceInit
(
&
registry_init_
,
&
InitRegistry
)
;
if
(
!
InsertIfNotPresent
(
registry_
,
make_pair
(
containing_type
,
number
),
info
))
{
...
...
src/google/protobuf/stubs/common.cc
View file @
63e646b7
...
...
@@ -31,10 +31,12 @@
// Author: kenton@google.com (Kenton Varda)
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <stdio.h>
#include <errno.h>
#include <vector>
#include "config.h"
...
...
@@ -114,26 +116,20 @@ void NullLogHandler(LogLevel level, const char* filename, int line,
static
LogHandler
*
log_handler_
=
&
DefaultLogHandler
;
static
int
log_silencer_count_
=
0
;
// Mutex which protects log_silencer_count_. We provide a static function to
// get it so that it is initialized on first use, which be during
// initialization time. If we just allocated it as a global variable, it might
// not be initialized before someone tries to use it.
static
Mutex
*
LogSilencerMutex
()
{
static
Mutex
*
log_silencer_count_mutex_
=
new
Mutex
;
return
log_silencer_count_mutex_
;
}
// Forces the above mutex to be initialized during startup. This way we don't
// have to worry about the initialization itself being thread-safe, since no
// threads should exist yet at startup time. (Otherwise we'd have no way to
// make things thread-safe here because we'd need a Mutex for that, and we'd
// have no way to construct one safely!)
static
struct
LogSilencerMutexInitializer
{
LogSilencerMutexInitializer
()
{
LogSilencerMutex
();
}
}
log_silencer_mutex_initializer
;
static
Mutex
*
log_silencer_count_mutex_
=
NULL
;
GOOGLE_PROTOBUF_DECLARE_ONCE
(
log_silencer_count_init_
);
void
DeleteLogSilencerCount
()
{
delete
log_silencer_count_mutex_
;
log_silencer_count_mutex_
=
NULL
;
}
void
InitLogSilencerCount
()
{
log_silencer_count_mutex_
=
new
Mutex
;
OnShutdown
(
&
DeleteLogSilencerCount
);
}
void
InitLogSilencerCountOnce
()
{
GoogleOnceInit
(
&
log_silencer_count_init_
,
&
InitLogSilencerCount
);
}
static
string
SimpleCtoa
(
char
c
)
{
return
string
(
1
,
c
);
}
...
...
@@ -160,7 +156,8 @@ void LogMessage::Finish() {
bool
suppress
=
false
;
if
(
level_
!=
LOGLEVEL_FATAL
)
{
MutexLock
lock
(
internal
::
LogSilencerMutex
());
InitLogSilencerCountOnce
();
MutexLock
lock
(
log_silencer_count_mutex_
);
suppress
=
internal
::
log_silencer_count_
>
0
;
}
...
...
@@ -193,12 +190,14 @@ LogHandler* SetLogHandler(LogHandler* new_func) {
}
LogSilencer
::
LogSilencer
()
{
MutexLock
lock
(
internal
::
LogSilencerMutex
());
internal
::
InitLogSilencerCountOnce
();
MutexLock
lock
(
internal
::
log_silencer_count_mutex_
);
++
internal
::
log_silencer_count_
;
};
LogSilencer
::~
LogSilencer
()
{
MutexLock
lock
(
internal
::
LogSilencerMutex
());
internal
::
InitLogSilencerCountOnce
();
MutexLock
lock
(
internal
::
log_silencer_count_mutex_
);
--
internal
::
log_silencer_count_
;
};
...
...
@@ -291,5 +290,51 @@ void Mutex::AssertHeld() {
#endif
// ===================================================================
// Shutdown support.
namespace
internal
{
typedef
void
OnShutdownFunc
();
vector
<
void
(
*
)()
>*
shutdown_functions
=
NULL
;
Mutex
*
shutdown_functions_mutex
=
NULL
;
GOOGLE_PROTOBUF_DECLARE_ONCE
(
shutdown_functions_init
);
void
InitShutdownFunctions
()
{
shutdown_functions
=
new
vector
<
void
(
*
)()
>
;
shutdown_functions_mutex
=
new
Mutex
;
}
inline
void
InitShutdownFunctionsOnce
()
{
GoogleOnceInit
(
&
shutdown_functions_init
,
&
InitShutdownFunctions
);
}
void
OnShutdown
(
void
(
*
func
)())
{
InitShutdownFunctionsOnce
();
MutexLock
lock
(
shutdown_functions_mutex
);
shutdown_functions
->
push_back
(
func
);
}
}
// namespace internal
void
ShutdownProtobufLibrary
()
{
internal
::
InitShutdownFunctionsOnce
();
// We don't need to lock shutdown_functions_mutex because it's up to the
// caller to make sure that no one is using the library before this is
// called.
// Make it safe to call this multiple times.
if
(
internal
::
shutdown_functions
==
NULL
)
return
;
for
(
int
i
=
0
;
i
<
internal
::
shutdown_functions
->
size
();
i
++
)
{
internal
::
shutdown_functions
->
at
(
i
)();
}
delete
internal
::
shutdown_functions
;
internal
::
shutdown_functions
=
NULL
;
delete
internal
::
shutdown_functions_mutex
;
internal
::
shutdown_functions_mutex
=
NULL
;
}
}
// namespace protobuf
}
// namespace google
src/google/protobuf/stubs/common.h
View file @
63e646b7
...
...
@@ -1085,6 +1085,31 @@ LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
}
// namespace internal
// ===================================================================
// Shutdown support.
// Shut down the entire protocol buffers library, deleting all static-duration
// objects allocated by the library or by generated .pb.cc files.
//
// There are two reasons you might want to call this:
// * You use a draconian definition of "memory leak" in which you expect
// every single malloc() to have a corresponding free(), even for objects
// which live until program exit.
// * You are writing a dynamically-loaded library which needs to clean up
// after itself when the library is unloaded.
//
// It is safe to call this multiple times. However, it is not safe to use
// any other part of the protocol buffers library after
// ShutdownProtobufLibrary() has been called.
LIBPROTOBUF_EXPORT
void
ShutdownProtobufLibrary
();
namespace
internal
{
// Register a function to be called when ShutdownProtocolBuffers() is called.
LIBPROTOBUF_EXPORT
void
OnShutdown
(
void
(
*
func
)());
}
// namespace internal
}
// namespace protobuf
}
// namespace google
...
...
src/google/protobuf/testing/googletest.cc
View file @
63e646b7
...
...
@@ -233,5 +233,19 @@ void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename,
}
}
namespace
{
// Force shutdown at process exit so that we can test for memory leaks. To
// actually check for leaks, I suggest using the heap checker included with
// google-perftools. Set it to "draconian" mode to ensure that every last
// call to malloc() has a corresponding free().
struct
ForceShutdown
{
~
ForceShutdown
()
{
ShutdownProtobufLibrary
();
}
}
force_shutdown
;
}
// namespace
}
// namespace protobuf
}
// namespace google
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment