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