1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/once.h> 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stdio.h> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <errno.h> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector> 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "config.h" 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _WIN32 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define WIN32_LEAN_AND_MEAN // We only need minimal includes 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <windows.h> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define snprintf _snprintf // see comment in strutil.cc 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#elif defined(HAVE_PTHREAD) 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <pthread.h> 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#error "No suitable threading library available." 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace internal { 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid VerifyVersion(int headerVersion, 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int minLibraryVersion, 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* filename) { 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) { 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Library is too old for headers. 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "This program requires version " << VersionString(minLibraryVersion) 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << " of the Protocol Buffer runtime library, but the installed version " 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update " 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "your library. If you compiled the program yourself, make sure that " 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "your headers are from the same version of Protocol Buffers as your " 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "link-time library. (Version verification failed in \"" 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << filename << "\".)"; 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (headerVersion < kMinHeaderVersionForLibrary) { 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Headers are too old for library. 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "This program was compiled against version " 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << VersionString(headerVersion) << " of the Protocol Buffer runtime " 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "library, which is not compatible with the installed version (" 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program " 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "author for an update. If you compiled the program yourself, make " 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "sure that your headers are from the same version of Protocol Buffers " 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "as your link-time library. (Version verification failed in \"" 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << filename << "\".)"; 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring VersionString(int version) { 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int major = version / 1000000; 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int minor = (version / 1000) % 1000; 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int micro = version % 1000; 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 128 bytes should always be enough, but we use snprintf() anyway to be 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // safe. 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[128]; 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro); 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Guard against broken MSVC snprintf(). 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[sizeof(buffer)-1] = '\0'; 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return buffer; 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace internal 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// emulates google3/base/logging.cc 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace internal { 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DefaultLogHandler(LogLevel level, const char* filename, int line, 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& message) { 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" }; 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We use fprintf() instead of cerr because we want this to work at static 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // initialization time. 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fprintf(stderr, "libprotobuf %s %s:%d] %s\n", 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville level_names[level], filename, line, message.c_str()); 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fflush(stderr); // Needed on MSVC. 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid NullLogHandler(LogLevel level, const char* filename, int line, 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& message) { 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Nothing. 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic LogHandler* log_handler_ = &DefaultLogHandler; 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic int log_silencer_count_ = 0; 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic Mutex* log_silencer_count_mutex_ = NULL; 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_); 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DeleteLogSilencerCount() { 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete log_silencer_count_mutex_; 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville log_silencer_count_mutex_ = NULL; 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid InitLogSilencerCount() { 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville log_silencer_count_mutex_ = new Mutex; 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OnShutdown(&DeleteLogSilencerCount); 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid InitLogSilencerCountOnce() { 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount); 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLogMessage& LogMessage::operator<<(const string& value) { 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_ += value; 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return *this; 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLogMessage& LogMessage::operator<<(const char* value) { 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_ += value; 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return *this; 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Since this is just for logging, we don't care if the current locale changes 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the results -- in fact, we probably prefer that. So we use snprintf() 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// instead of Simple*toa(). 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef DECLARE_STREAM_OPERATOR 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \ 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LogMessage& LogMessage::operator<<(TYPE value) { \ 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /* 128 bytes should be big enough for any of the primitive */ \ 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /* values which we print with this, but well use snprintf() */ \ 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /* anyway to be extra safe. */ \ 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[128]; \ 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville snprintf(buffer, sizeof(buffer), FORMAT, value); \ 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville /* Guard against broken MSVC snprintf(). */ \ 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[sizeof(buffer)-1] = '\0'; \ 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_ += buffer; \ 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return *this; \ 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDECLARE_STREAM_OPERATOR(char , "%c" ) 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDECLARE_STREAM_OPERATOR(int , "%d" ) 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDECLARE_STREAM_OPERATOR(uint , "%u" ) 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDECLARE_STREAM_OPERATOR(long , "%ld") 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDECLARE_STREAM_OPERATOR(unsigned long, "%lu") 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDECLARE_STREAM_OPERATOR(double , "%g" ) 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef DECLARE_STREAM_OPERATOR 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLogMessage::LogMessage(LogLevel level, const char* filename, int line) 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : level_(level), filename_(filename), line_(line) {} 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLogMessage::~LogMessage() {} 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid LogMessage::Finish() { 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool suppress = false; 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (level_ != LOGLEVEL_FATAL) { 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InitLogSilencerCountOnce(); 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLock lock(log_silencer_count_mutex_); 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville suppress = internal::log_silencer_count_ > 0; 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!suppress) { 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::log_handler_(level_, filename_, line_, message_); 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (level_ == LOGLEVEL_FATAL) { 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville abort(); 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid LogFinisher::operator=(LogMessage& other) { 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville other.Finish(); 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace internal 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLogHandler* SetLogHandler(LogHandler* new_func) { 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LogHandler* old = internal::log_handler_; 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (old == &internal::NullLogHandler) { 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville old = NULL; 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (new_func == NULL) { 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::log_handler_ = &internal::NullLogHandler; 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::log_handler_ = new_func; 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return old; 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLogSilencer::LogSilencer() { 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::InitLogSilencerCountOnce(); 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLock lock(internal::log_silencer_count_mutex_); 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++internal::log_silencer_count_; 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleLogSilencer::~LogSilencer() { 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::InitLogSilencerCountOnce(); 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLock lock(internal::log_silencer_count_mutex_); 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville --internal::log_silencer_count_; 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// emulates google3/base/callback.cc 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleClosure::~Closure() {} 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace internal { FunctionClosure0::~FunctionClosure0() {} } 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DoNothing() {} 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// emulates google3/base/mutex.cc 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _WIN32 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct Mutex::Internal { 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CRITICAL_SECTION mutex; 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef NDEBUG 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Used only to implement AssertHeld(). 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DWORD thread_id; 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMutex::Mutex() 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : mInternal(new Internal) { 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InitializeCriticalSection(&mInternal->mutex); 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMutex::~Mutex() { 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DeleteCriticalSection(&mInternal->mutex); 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete mInternal; 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Mutex::Lock() { 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnterCriticalSection(&mInternal->mutex); 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef NDEBUG 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville mInternal->thread_id = GetCurrentThreadId(); 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Mutex::Unlock() { 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef NDEBUG 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville mInternal->thread_id = 0; 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LeaveCriticalSection(&mInternal->mutex); 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Mutex::AssertHeld() { 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef NDEBUG 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#elif defined(HAVE_PTHREAD) 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct Mutex::Internal { 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pthread_mutex_t mutex; 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMutex::Mutex() 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : mInternal(new Internal) { 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pthread_mutex_init(&mInternal->mutex, NULL); 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMutex::~Mutex() { 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pthread_mutex_destroy(&mInternal->mutex); 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete mInternal; 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Mutex::Lock() { 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result = pthread_mutex_lock(&mInternal->mutex); 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != 0) { 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Mutex::Unlock() { 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result = pthread_mutex_unlock(&mInternal->mutex); 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != 0) { 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Mutex::AssertHeld() { 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // pthreads dosn't provide a way to check which thread holds the mutex. 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // TODO(kenton): Maybe keep track of locking thread ID like with WIN32? 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Shutdown support. 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace internal { 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef void OnShutdownFunc(); 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevector<void (*)()>* shutdown_functions = NULL; 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMutex* shutdown_functions_mutex = NULL; 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init); 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid InitShutdownFunctions() { 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville shutdown_functions = new vector<void (*)()>; 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville shutdown_functions_mutex = new Mutex; 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline void InitShutdownFunctionsOnce() { 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions); 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid OnShutdown(void (*func)()) { 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InitShutdownFunctionsOnce(); 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLock lock(shutdown_functions_mutex); 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville shutdown_functions->push_back(func); 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace internal 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ShutdownProtobufLibrary() { 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::InitShutdownFunctionsOnce(); 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We don't need to lock shutdown_functions_mutex because it's up to the 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // caller to make sure that no one is using the library before this is 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // called. 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make it safe to call this multiple times. 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (internal::shutdown_functions == NULL) return; 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < internal::shutdown_functions->size(); i++) { 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::shutdown_functions->at(i)(); 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete internal::shutdown_functions; 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::shutdown_functions = NULL; 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete internal::shutdown_functions_mutex; 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::shutdown_functions_mutex = NULL; 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 366