aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/stubs
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/stubs')
-rw-r--r--src/google/protobuf/stubs/common.cc64
-rw-r--r--src/google/protobuf/stubs/common.h15
2 files changed, 30 insertions, 49 deletions
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index 33d24c57..6544c6ed 100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -339,66 +339,42 @@ namespace internal {
typedef void OnShutdownFunc();
struct ShutdownData {
~ShutdownData() {
- for (int i = 0; i < functions.size(); i++) {
- functions[i]();
- }
- for (int i = 0; i < strings.size(); i++) {
- strings[i]->~string();
- }
- for (int i = 0; i < messages.size(); i++) {
- messages[i]->~MessageLite();
- }
+ std::reverse(functions.begin(), functions.end());
+ for (auto pair : functions) pair.first(pair.second);
}
- std::vector<void (*)()> functions;
- std::vector<const std::string*> strings;
- std::vector<const MessageLite*> messages;
+ static ShutdownData* get() {
+ static auto* data = new ShutdownData;
+ return data;
+ }
+
+ std::vector<std::pair<void (*)(const void*), const void*>> functions;
Mutex mutex;
};
-ShutdownData* shutdown_data = NULL;
-GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
-
-void InitShutdownFunctions() {
- shutdown_data = new ShutdownData;
-}
-
-inline void InitShutdownFunctionsOnce() {
- GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
+static void RunZeroArgFunc(const void* arg) {
+ reinterpret_cast<void (*)()>(const_cast<void*>(arg))();
}
void OnShutdown(void (*func)()) {
- InitShutdownFunctionsOnce();
- MutexLock lock(&shutdown_data->mutex);
- shutdown_data->functions.push_back(func);
+ OnShutdownRun(RunZeroArgFunc, reinterpret_cast<void*>(func));
}
-void OnShutdownDestroyString(const std::string* ptr) {
- InitShutdownFunctionsOnce();
+void OnShutdownRun(void (*f)(const void*), const void* arg) {
+ auto shutdown_data = ShutdownData::get();
MutexLock lock(&shutdown_data->mutex);
- shutdown_data->strings.push_back(ptr);
-}
-
-void OnShutdownDestroyMessage(const void* ptr) {
- InitShutdownFunctionsOnce();
- MutexLock lock(&shutdown_data->mutex);
- shutdown_data->messages.push_back(static_cast<const MessageLite*>(ptr));
+ shutdown_data->functions.push_back(std::make_pair(f, arg));
}
} // 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_data == NULL) return;
-
- delete internal::shutdown_data;
- internal::shutdown_data = NULL;
+ // This function should be called only once, but accepts multiple calls.
+ static bool is_shutdown = false;
+ if (!is_shutdown) {
+ delete internal::ShutdownData::get();
+ is_shutdown = true;
+ }
}
#if PROTOBUF_USE_EXCEPTIONS
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index 5d320764..f505f46a 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -193,17 +193,22 @@ LIBPROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid(
//
// 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.
+// ShutdownProtobufLibrary() has been called. Furthermore this call is not
+// thread safe, user needs to synchronize multiple calls.
LIBPROTOBUF_EXPORT void ShutdownProtobufLibrary();
namespace internal {
// Register a function to be called when ShutdownProtocolBuffers() is called.
LIBPROTOBUF_EXPORT void OnShutdown(void (*func)());
-// Destroy the string (call string destructor)
-LIBPROTOBUF_EXPORT void OnShutdownDestroyString(const std::string* ptr);
-// Destroy (not delete) the message
-LIBPROTOBUF_EXPORT void OnShutdownDestroyMessage(const void* ptr);
+// Run an arbitrary function on an arg
+LIBPROTOBUF_EXPORT void OnShutdownRun(void (*f)(const void*), const void* arg);
+
+template <typename T>
+T* OnShutdownDelete(T* p) {
+ OnShutdownRun([](const void* p) { delete static_cast<const T*>(p); }, p);
+ return p;
+}
} // namespace internal