1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc. All rights reserved.
3
// http://code.google.com/p/protobuf/
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
9
// * Redistributions of source code must retain the above copyright
10
// notice, this list of conditions and the following disclaimer.
11
// * Redistributions in binary form must reproduce the above
12
// copyright notice, this list of conditions and the following disclaimer
13
// in the documentation and/or other materials provided with the
15
// * Neither the name of Google Inc. nor the names of its
16
// contributors may be used to endorse or promote products derived from
17
// this software without specific prior written permission.
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
// Author: kenton@google.com (Kenton Varda)
33
#include <google/protobuf/stubs/common.h>
34
#include <google/protobuf/stubs/once.h>
42
#define WIN32_LEAN_AND_MEAN // We only need minimal includes
44
#define snprintf _snprintf // see comment in strutil.cc
45
#elif defined(HAVE_PTHREAD)
48
#error "No suitable threading library available."
56
void VerifyVersion(int headerVersion,
57
int minLibraryVersion,
58
const char* filename) {
59
if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
60
// Library is too old for headers.
62
<< "This program requires version " << VersionString(minLibraryVersion)
63
<< " of the Protocol Buffer runtime library, but the installed version "
64
"is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update "
65
"your library. If you compiled the program yourself, make sure that "
66
"your headers are from the same version of Protocol Buffers as your "
67
"link-time library. (Version verification failed in \""
68
<< filename << "\".)";
70
if (headerVersion < kMinHeaderVersionForLibrary) {
71
// Headers are too old for library.
73
<< "This program was compiled against version "
74
<< VersionString(headerVersion) << " of the Protocol Buffer runtime "
75
"library, which is not compatible with the installed version ("
76
<< VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program "
77
"author for an update. If you compiled the program yourself, make "
78
"sure that your headers are from the same version of Protocol Buffers "
79
"as your link-time library. (Version verification failed in \""
80
<< filename << "\".)";
84
string VersionString(int version) {
85
int major = version / 1000000;
86
int minor = (version / 1000) % 1000;
87
int micro = version % 1000;
89
// 128 bytes should always be enough, but we use snprintf() anyway to be
92
snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
94
// Guard against broken MSVC snprintf().
95
buffer[sizeof(buffer)-1] = '\0';
100
} // namespace internal
102
// ===================================================================
103
// emulates google3/base/logging.cc
107
void DefaultLogHandler(LogLevel level, const char* filename, int line,
108
const string& message) {
109
static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
111
// We use fprintf() instead of cerr because we want this to work at static
112
// initialization time.
113
fprintf(stderr, "libprotobuf %s %s:%d] %s\n",
114
level_names[level], filename, line, message.c_str());
115
fflush(stderr); // Needed on MSVC.
118
void NullLogHandler(LogLevel level, const char* filename, int line,
119
const string& message) {
123
static LogHandler* log_handler_ = &DefaultLogHandler;
124
static int log_silencer_count_ = 0;
126
static Mutex* log_silencer_count_mutex_ = NULL;
127
GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
129
void DeleteLogSilencerCount() {
130
delete log_silencer_count_mutex_;
131
log_silencer_count_mutex_ = NULL;
133
void InitLogSilencerCount() {
134
log_silencer_count_mutex_ = new Mutex;
135
OnShutdown(&DeleteLogSilencerCount);
137
void InitLogSilencerCountOnce() {
138
GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
141
LogMessage& LogMessage::operator<<(const string& value) {
146
LogMessage& LogMessage::operator<<(const char* value) {
151
// Since this is just for logging, we don't care if the current locale changes
152
// the results -- in fact, we probably prefer that. So we use snprintf()
153
// instead of Simple*toa().
154
#undef DECLARE_STREAM_OPERATOR
155
#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \
156
LogMessage& LogMessage::operator<<(TYPE value) { \
157
/* 128 bytes should be big enough for any of the primitive */ \
158
/* values which we print with this, but well use snprintf() */ \
159
/* anyway to be extra safe. */ \
161
snprintf(buffer, sizeof(buffer), FORMAT, value); \
162
/* Guard against broken MSVC snprintf(). */ \
163
buffer[sizeof(buffer)-1] = '\0'; \
164
message_ += buffer; \
168
DECLARE_STREAM_OPERATOR(char , "%c" )
169
DECLARE_STREAM_OPERATOR(int , "%d" )
170
DECLARE_STREAM_OPERATOR(uint , "%u" )
171
DECLARE_STREAM_OPERATOR(long , "%ld")
172
DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
173
DECLARE_STREAM_OPERATOR(double , "%g" )
174
#undef DECLARE_STREAM_OPERATOR
176
LogMessage::LogMessage(LogLevel level, const char* filename, int line)
177
: level_(level), filename_(filename), line_(line) {}
178
LogMessage::~LogMessage() {}
180
void LogMessage::Finish() {
181
bool suppress = false;
183
if (level_ != LOGLEVEL_FATAL) {
184
InitLogSilencerCountOnce();
185
MutexLock lock(log_silencer_count_mutex_);
186
suppress = internal::log_silencer_count_ > 0;
190
internal::log_handler_(level_, filename_, line_, message_);
193
if (level_ == LOGLEVEL_FATAL) {
198
void LogFinisher::operator=(LogMessage& other) {
202
} // namespace internal
204
LogHandler* SetLogHandler(LogHandler* new_func) {
205
LogHandler* old = internal::log_handler_;
206
if (old == &internal::NullLogHandler) {
209
if (new_func == NULL) {
210
internal::log_handler_ = &internal::NullLogHandler;
212
internal::log_handler_ = new_func;
217
LogSilencer::LogSilencer() {
218
internal::InitLogSilencerCountOnce();
219
MutexLock lock(internal::log_silencer_count_mutex_);
220
++internal::log_silencer_count_;
223
LogSilencer::~LogSilencer() {
224
internal::InitLogSilencerCountOnce();
225
MutexLock lock(internal::log_silencer_count_mutex_);
226
--internal::log_silencer_count_;
229
// ===================================================================
230
// emulates google3/base/callback.cc
232
Closure::~Closure() {}
234
namespace internal { FunctionClosure0::~FunctionClosure0() {} }
238
// ===================================================================
239
// emulates google3/base/mutex.cc
243
struct Mutex::Internal {
244
CRITICAL_SECTION mutex;
246
// Used only to implement AssertHeld().
252
: mInternal(new Internal) {
253
InitializeCriticalSection(&mInternal->mutex);
257
DeleteCriticalSection(&mInternal->mutex);
262
EnterCriticalSection(&mInternal->mutex);
264
mInternal->thread_id = GetCurrentThreadId();
268
void Mutex::Unlock() {
270
mInternal->thread_id = 0;
272
LeaveCriticalSection(&mInternal->mutex);
275
void Mutex::AssertHeld() {
277
GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
281
#elif defined(HAVE_PTHREAD)
283
struct Mutex::Internal {
284
pthread_mutex_t mutex;
288
: mInternal(new Internal) {
289
pthread_mutex_init(&mInternal->mutex, NULL);
293
pthread_mutex_destroy(&mInternal->mutex);
298
int result = pthread_mutex_lock(&mInternal->mutex);
300
GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
304
void Mutex::Unlock() {
305
int result = pthread_mutex_unlock(&mInternal->mutex);
307
GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
311
void Mutex::AssertHeld() {
312
// pthreads dosn't provide a way to check which thread holds the mutex.
313
// TODO(kenton): Maybe keep track of locking thread ID like with WIN32?
318
// ===================================================================
323
typedef void OnShutdownFunc();
324
vector<void (*)()>* shutdown_functions = NULL;
325
Mutex* shutdown_functions_mutex = NULL;
326
GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
328
void InitShutdownFunctions() {
329
shutdown_functions = new vector<void (*)()>;
330
shutdown_functions_mutex = new Mutex;
333
inline void InitShutdownFunctionsOnce() {
334
GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
337
void OnShutdown(void (*func)()) {
338
InitShutdownFunctionsOnce();
339
MutexLock lock(shutdown_functions_mutex);
340
shutdown_functions->push_back(func);
343
} // namespace internal
345
void ShutdownProtobufLibrary() {
346
internal::InitShutdownFunctionsOnce();
348
// We don't need to lock shutdown_functions_mutex because it's up to the
349
// caller to make sure that no one is using the library before this is
352
// Make it safe to call this multiple times.
353
if (internal::shutdown_functions == NULL) return;
355
for (int i = 0; i < internal::shutdown_functions->size(); i++) {
356
internal::shutdown_functions->at(i)();
358
delete internal::shutdown_functions;
359
internal::shutdown_functions = NULL;
360
delete internal::shutdown_functions_mutex;
361
internal::shutdown_functions_mutex = NULL;
364
} // namespace protobuf
365
} // namespace google