diff options
Diffstat (limited to 'src/google/protobuf/stubs/common.cc')
-rwxr-xr-x[-rw-r--r--] | src/google/protobuf/stubs/common.cc | 146 |
1 files changed, 50 insertions, 96 deletions
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index 54dbafab..33d24c57 100644..100755 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -30,6 +30,7 @@ // Author: kenton@google.com (Kenton Varda) +#include <google/protobuf/message_lite.h> // TODO(gerbens) ideally remove this. #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/once.h> #include <google/protobuf/stubs/status.h> @@ -108,11 +109,17 @@ string VersionString(int version) { // =================================================================== // emulates google3/base/logging.cc +// If the minimum logging level is not set, we default to logging messages for +// all levels. +#ifndef GOOGLE_PROTOBUF_MIN_LOG_LEVEL +#define GOOGLE_PROTOBUF_MIN_LOG_LEVEL LOGLEVEL_INFO +#endif + namespace internal { + #if defined(__ANDROID__) inline void DefaultLogHandler(LogLevel level, const char* filename, int line, const string& message) { -#ifdef GOOGLE_PROTOBUF_MIN_LOG_LEVEL if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { return; } @@ -143,11 +150,14 @@ inline void DefaultLogHandler(LogLevel level, const char* filename, int line, __android_log_write(ANDROID_LOG_FATAL, "libprotobuf-native", "terminating.\n"); } -#endif } + #else void DefaultLogHandler(LogLevel level, const char* filename, int line, const string& message) { + if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { + return; + } static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" }; // We use fprintf() instead of cerr because we want this to work at static @@ -304,86 +314,6 @@ namespace internal { FunctionClosure0::~FunctionClosure0() {} } void DoNothing() {} // =================================================================== -// emulates google3/base/mutex.cc - -#ifdef _WIN32 - -struct Mutex::Internal { - CRITICAL_SECTION mutex; -#ifndef NDEBUG - // Used only to implement AssertHeld(). - DWORD thread_id; -#endif -}; - -Mutex::Mutex() - : mInternal(new Internal) { - InitializeCriticalSection(&mInternal->mutex); -} - -Mutex::~Mutex() { - DeleteCriticalSection(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - EnterCriticalSection(&mInternal->mutex); -#ifndef NDEBUG - mInternal->thread_id = GetCurrentThreadId(); -#endif -} - -void Mutex::Unlock() { -#ifndef NDEBUG - mInternal->thread_id = 0; -#endif - LeaveCriticalSection(&mInternal->mutex); -} - -void Mutex::AssertHeld() { -#ifndef NDEBUG - GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); -#endif -} - -#elif defined(HAVE_PTHREAD) - -struct Mutex::Internal { - pthread_mutex_t mutex; -}; - -Mutex::Mutex() - : mInternal(new Internal) { - pthread_mutex_init(&mInternal->mutex, NULL); -} - -Mutex::~Mutex() { - pthread_mutex_destroy(&mInternal->mutex); - delete mInternal; -} - -void Mutex::Lock() { - int result = pthread_mutex_lock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); - } -} - -void Mutex::Unlock() { - int result = pthread_mutex_unlock(&mInternal->mutex); - if (result != 0) { - GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); - } -} - -void Mutex::AssertHeld() { - // pthreads dosn't provide a way to check which thread holds the mutex. - // TODO(kenton): Maybe keep track of locking thread ID like with WIN32? -} - -#endif - -// =================================================================== // emulates google3/util/endian/endian.h // // TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in @@ -407,13 +337,30 @@ uint32 ghtonl(uint32 x) { namespace internal { typedef void OnShutdownFunc(); -vector<void (*)()>* shutdown_functions = NULL; -Mutex* shutdown_functions_mutex = NULL; +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::vector<void (*)()> functions; + std::vector<const std::string*> strings; + std::vector<const MessageLite*> messages; + Mutex mutex; +}; + +ShutdownData* shutdown_data = NULL; GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init); void InitShutdownFunctions() { - shutdown_functions = new vector<void (*)()>; - shutdown_functions_mutex = new Mutex; + shutdown_data = new ShutdownData; } inline void InitShutdownFunctionsOnce() { @@ -422,8 +369,20 @@ inline void InitShutdownFunctionsOnce() { void OnShutdown(void (*func)()) { InitShutdownFunctionsOnce(); - MutexLock lock(shutdown_functions_mutex); - shutdown_functions->push_back(func); + MutexLock lock(&shutdown_data->mutex); + shutdown_data->functions.push_back(func); +} + +void OnShutdownDestroyString(const std::string* ptr) { + InitShutdownFunctionsOnce(); + 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)); } } // namespace internal @@ -436,15 +395,10 @@ void ShutdownProtobufLibrary() { // called. // Make it safe to call this multiple times. - if (internal::shutdown_functions == NULL) return; + if (internal::shutdown_data == 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; + delete internal::shutdown_data; + internal::shutdown_data = NULL; } #if PROTOBUF_USE_EXCEPTIONS |