1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 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 14 // distribution. 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. 18 // 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. 30 31 // Author: kenton (at) google.com (Kenton Varda) 32 33 #include <google/protobuf/stubs/common.h> 34 #include <google/protobuf/stubs/once.h> 35 #include <stdio.h> 36 #include <errno.h> 37 #include <vector> 38 39 #include "config.h" 40 41 #ifdef _WIN32 42 #define WIN32_LEAN_AND_MEAN // We only need minimal includes 43 #include <windows.h> 44 #define snprintf _snprintf // see comment in strutil.cc 45 #elif defined(HAVE_PTHREAD) 46 #include <pthread.h> 47 #else 48 #error "No suitable threading library available." 49 #endif 50 51 namespace google { 52 namespace protobuf { 53 54 namespace internal { 55 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. 61 GOOGLE_LOG(FATAL) 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 << "\".)"; 69 } 70 if (headerVersion < kMinHeaderVersionForLibrary) { 71 // Headers are too old for library. 72 GOOGLE_LOG(FATAL) 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 << "\".)"; 81 } 82 } 83 84 string VersionString(int version) { 85 int major = version / 1000000; 86 int minor = (version / 1000) % 1000; 87 int micro = version % 1000; 88 89 // 128 bytes should always be enough, but we use snprintf() anyway to be 90 // safe. 91 char buffer[128]; 92 snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro); 93 94 // Guard against broken MSVC snprintf(). 95 buffer[sizeof(buffer)-1] = '\0'; 96 97 return buffer; 98 } 99 100 } // namespace internal 101 102 // =================================================================== 103 // emulates google3/base/logging.cc 104 105 namespace internal { 106 107 void DefaultLogHandler(LogLevel level, const char* filename, int line, 108 const string& message) { 109 static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" }; 110 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. 116 } 117 118 void NullLogHandler(LogLevel level, const char* filename, int line, 119 const string& message) { 120 // Nothing. 121 } 122 123 static LogHandler* log_handler_ = &DefaultLogHandler; 124 static int log_silencer_count_ = 0; 125 126 static Mutex* log_silencer_count_mutex_ = NULL; 127 GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_); 128 129 void DeleteLogSilencerCount() { 130 delete log_silencer_count_mutex_; 131 log_silencer_count_mutex_ = NULL; 132 } 133 void InitLogSilencerCount() { 134 log_silencer_count_mutex_ = new Mutex; 135 OnShutdown(&DeleteLogSilencerCount); 136 } 137 void InitLogSilencerCountOnce() { 138 GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount); 139 } 140 141 LogMessage& LogMessage::operator<<(const string& value) { 142 message_ += value; 143 return *this; 144 } 145 146 LogMessage& LogMessage::operator<<(const char* value) { 147 message_ += value; 148 return *this; 149 } 150 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. */ \ 160 char buffer[128]; \ 161 snprintf(buffer, sizeof(buffer), FORMAT, value); \ 162 /* Guard against broken MSVC snprintf(). */ \ 163 buffer[sizeof(buffer)-1] = '\0'; \ 164 message_ += buffer; \ 165 return *this; \ 166 } 167 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 175 176 LogMessage::LogMessage(LogLevel level, const char* filename, int line) 177 : level_(level), filename_(filename), line_(line) {} 178 LogMessage::~LogMessage() {} 179 180 void LogMessage::Finish() { 181 bool suppress = false; 182 183 if (level_ != LOGLEVEL_FATAL) { 184 InitLogSilencerCountOnce(); 185 MutexLock lock(log_silencer_count_mutex_); 186 suppress = log_silencer_count_ > 0; 187 } 188 189 if (!suppress) { 190 log_handler_(level_, filename_, line_, message_); 191 } 192 193 if (level_ == LOGLEVEL_FATAL) { 194 #if PROTOBUF_USE_EXCEPTIONS 195 throw FatalException(filename_, line_, message_); 196 #else 197 abort(); 198 #endif 199 } 200 } 201 202 void LogFinisher::operator=(LogMessage& other) { 203 other.Finish(); 204 } 205 206 } // namespace internal 207 208 LogHandler* SetLogHandler(LogHandler* new_func) { 209 LogHandler* old = internal::log_handler_; 210 if (old == &internal::NullLogHandler) { 211 old = NULL; 212 } 213 if (new_func == NULL) { 214 internal::log_handler_ = &internal::NullLogHandler; 215 } else { 216 internal::log_handler_ = new_func; 217 } 218 return old; 219 } 220 221 LogSilencer::LogSilencer() { 222 internal::InitLogSilencerCountOnce(); 223 MutexLock lock(internal::log_silencer_count_mutex_); 224 ++internal::log_silencer_count_; 225 }; 226 227 LogSilencer::~LogSilencer() { 228 internal::InitLogSilencerCountOnce(); 229 MutexLock lock(internal::log_silencer_count_mutex_); 230 --internal::log_silencer_count_; 231 }; 232 233 // =================================================================== 234 // emulates google3/base/callback.cc 235 236 Closure::~Closure() {} 237 238 namespace internal { FunctionClosure0::~FunctionClosure0() {} } 239 240 void DoNothing() {} 241 242 // =================================================================== 243 // emulates google3/base/mutex.cc 244 245 #ifdef _WIN32 246 247 struct Mutex::Internal { 248 CRITICAL_SECTION mutex; 249 #ifndef NDEBUG 250 // Used only to implement AssertHeld(). 251 DWORD thread_id; 252 #endif 253 }; 254 255 Mutex::Mutex() 256 : mInternal(new Internal) { 257 InitializeCriticalSection(&mInternal->mutex); 258 } 259 260 Mutex::~Mutex() { 261 DeleteCriticalSection(&mInternal->mutex); 262 delete mInternal; 263 } 264 265 void Mutex::Lock() { 266 EnterCriticalSection(&mInternal->mutex); 267 #ifndef NDEBUG 268 mInternal->thread_id = GetCurrentThreadId(); 269 #endif 270 } 271 272 void Mutex::Unlock() { 273 #ifndef NDEBUG 274 mInternal->thread_id = 0; 275 #endif 276 LeaveCriticalSection(&mInternal->mutex); 277 } 278 279 void Mutex::AssertHeld() { 280 #ifndef NDEBUG 281 GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); 282 #endif 283 } 284 285 #elif defined(HAVE_PTHREAD) 286 287 struct Mutex::Internal { 288 pthread_mutex_t mutex; 289 }; 290 291 Mutex::Mutex() 292 : mInternal(new Internal) { 293 pthread_mutex_init(&mInternal->mutex, NULL); 294 } 295 296 Mutex::~Mutex() { 297 pthread_mutex_destroy(&mInternal->mutex); 298 delete mInternal; 299 } 300 301 void Mutex::Lock() { 302 int result = pthread_mutex_lock(&mInternal->mutex); 303 if (result != 0) { 304 GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); 305 } 306 } 307 308 void Mutex::Unlock() { 309 int result = pthread_mutex_unlock(&mInternal->mutex); 310 if (result != 0) { 311 GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); 312 } 313 } 314 315 void Mutex::AssertHeld() { 316 // pthreads dosn't provide a way to check which thread holds the mutex. 317 // TODO(kenton): Maybe keep track of locking thread ID like with WIN32? 318 } 319 320 #endif 321 322 // =================================================================== 323 // emulates google3/util/endian/endian.h 324 // 325 // TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in 326 // google/protobuf/io/coded_stream.h and therefore can not be used here. 327 // Maybe move that macro definition here in the furture. 328 uint32 ghtonl(uint32 x) { 329 union { 330 uint32 result; 331 uint8 result_array[4]; 332 }; 333 result_array[0] = static_cast<uint8>(x >> 24); 334 result_array[1] = static_cast<uint8>((x >> 16) & 0xFF); 335 result_array[2] = static_cast<uint8>((x >> 8) & 0xFF); 336 result_array[3] = static_cast<uint8>(x & 0xFF); 337 return result; 338 } 339 340 // =================================================================== 341 // Shutdown support. 342 343 namespace internal { 344 345 typedef void OnShutdownFunc(); 346 vector<void (*)()>* shutdown_functions = NULL; 347 Mutex* shutdown_functions_mutex = NULL; 348 GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init); 349 350 void InitShutdownFunctions() { 351 shutdown_functions = new vector<void (*)()>; 352 shutdown_functions_mutex = new Mutex; 353 } 354 355 inline void InitShutdownFunctionsOnce() { 356 GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions); 357 } 358 359 void OnShutdown(void (*func)()) { 360 InitShutdownFunctionsOnce(); 361 MutexLock lock(shutdown_functions_mutex); 362 shutdown_functions->push_back(func); 363 } 364 365 } // namespace internal 366 367 void ShutdownProtobufLibrary() { 368 internal::InitShutdownFunctionsOnce(); 369 370 // We don't need to lock shutdown_functions_mutex because it's up to the 371 // caller to make sure that no one is using the library before this is 372 // called. 373 374 // Make it safe to call this multiple times. 375 if (internal::shutdown_functions == NULL) return; 376 377 for (int i = 0; i < internal::shutdown_functions->size(); i++) { 378 internal::shutdown_functions->at(i)(); 379 } 380 delete internal::shutdown_functions; 381 internal::shutdown_functions = NULL; 382 delete internal::shutdown_functions_mutex; 383 internal::shutdown_functions_mutex = NULL; 384 } 385 386 #if PROTOBUF_USE_EXCEPTIONS 387 FatalException::~FatalException() throw() {} 388 389 const char* FatalException::what() const throw() { 390 return message_.c_str(); 391 } 392 #endif 393 394 } // namespace protobuf 395 } // namespace google 396