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 = internal::log_silencer_count_ > 0; 187 } 188 189 if (!suppress) { 190 internal::log_handler_(level_, filename_, line_, message_); 191 } 192 193 if (level_ == LOGLEVEL_FATAL) { 194 abort(); 195 } 196 } 197 198 void LogFinisher::operator=(LogMessage& other) { 199 other.Finish(); 200 } 201 202 } // namespace internal 203 204 LogHandler* SetLogHandler(LogHandler* new_func) { 205 LogHandler* old = internal::log_handler_; 206 if (old == &internal::NullLogHandler) { 207 old = NULL; 208 } 209 if (new_func == NULL) { 210 internal::log_handler_ = &internal::NullLogHandler; 211 } else { 212 internal::log_handler_ = new_func; 213 } 214 return old; 215 } 216 217 LogSilencer::LogSilencer() { 218 internal::InitLogSilencerCountOnce(); 219 MutexLock lock(internal::log_silencer_count_mutex_); 220 ++internal::log_silencer_count_; 221 }; 222 223 LogSilencer::~LogSilencer() { 224 internal::InitLogSilencerCountOnce(); 225 MutexLock lock(internal::log_silencer_count_mutex_); 226 --internal::log_silencer_count_; 227 }; 228 229 // =================================================================== 230 // emulates google3/base/callback.cc 231 232 Closure::~Closure() {} 233 234 namespace internal { FunctionClosure0::~FunctionClosure0() {} } 235 236 void DoNothing() {} 237 238 // =================================================================== 239 // emulates google3/base/mutex.cc 240 241 #ifdef _WIN32 242 243 struct Mutex::Internal { 244 CRITICAL_SECTION mutex; 245 #ifndef NDEBUG 246 // Used only to implement AssertHeld(). 247 DWORD thread_id; 248 #endif 249 }; 250 251 Mutex::Mutex() 252 : mInternal(new Internal) { 253 InitializeCriticalSection(&mInternal->mutex); 254 } 255 256 Mutex::~Mutex() { 257 DeleteCriticalSection(&mInternal->mutex); 258 delete mInternal; 259 } 260 261 void Mutex::Lock() { 262 EnterCriticalSection(&mInternal->mutex); 263 #ifndef NDEBUG 264 mInternal->thread_id = GetCurrentThreadId(); 265 #endif 266 } 267 268 void Mutex::Unlock() { 269 #ifndef NDEBUG 270 mInternal->thread_id = 0; 271 #endif 272 LeaveCriticalSection(&mInternal->mutex); 273 } 274 275 void Mutex::AssertHeld() { 276 #ifndef NDEBUG 277 GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId()); 278 #endif 279 } 280 281 #elif defined(HAVE_PTHREAD) 282 283 struct Mutex::Internal { 284 pthread_mutex_t mutex; 285 }; 286 287 Mutex::Mutex() 288 : mInternal(new Internal) { 289 pthread_mutex_init(&mInternal->mutex, NULL); 290 } 291 292 Mutex::~Mutex() { 293 pthread_mutex_destroy(&mInternal->mutex); 294 delete mInternal; 295 } 296 297 void Mutex::Lock() { 298 int result = pthread_mutex_lock(&mInternal->mutex); 299 if (result != 0) { 300 GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result); 301 } 302 } 303 304 void Mutex::Unlock() { 305 int result = pthread_mutex_unlock(&mInternal->mutex); 306 if (result != 0) { 307 GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result); 308 } 309 } 310 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? 314 } 315 316 #endif 317 318 // =================================================================== 319 // Shutdown support. 320 321 namespace internal { 322 323 typedef void OnShutdownFunc(); 324 vector<void (*)()>* shutdown_functions = NULL; 325 Mutex* shutdown_functions_mutex = NULL; 326 GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init); 327 328 void InitShutdownFunctions() { 329 shutdown_functions = new vector<void (*)()>; 330 shutdown_functions_mutex = new Mutex; 331 } 332 333 inline void InitShutdownFunctionsOnce() { 334 GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions); 335 } 336 337 void OnShutdown(void (*func)()) { 338 InitShutdownFunctionsOnce(); 339 MutexLock lock(shutdown_functions_mutex); 340 shutdown_functions->push_back(func); 341 } 342 343 } // namespace internal 344 345 void ShutdownProtobufLibrary() { 346 internal::InitShutdownFunctionsOnce(); 347 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 350 // called. 351 352 // Make it safe to call this multiple times. 353 if (internal::shutdown_functions == NULL) return; 354 355 for (int i = 0; i < internal::shutdown_functions->size(); i++) { 356 internal::shutdown_functions->at(i)(); 357 } 358 delete internal::shutdown_functions; 359 internal::shutdown_functions = NULL; 360 delete internal::shutdown_functions_mutex; 361 internal::shutdown_functions_mutex = NULL; 362 } 363 364 } // namespace protobuf 365 } // namespace google 366