/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/stubs/common.cc

http://github.com/tomahawk-player/tomahawk · C++ · 377 lines · 253 code · 68 blank · 56 comment · 19 complexity · 59ff55516ea14bf0f0763480e8a707e6 MD5 · raw file

  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. // Author: kenton@google.com (Kenton Varda)
  31. #include <google/protobuf/stubs/common.h>
  32. #include <google/protobuf/stubs/once.h>
  33. #include <stdio.h>
  34. #include <errno.h>
  35. #include <vector>
  36. #include "config.h"
  37. #ifdef _WIN32
  38. #define WIN32_LEAN_AND_MEAN // We only need minimal includes
  39. #include <windows.h>
  40. #define snprintf _snprintf // see comment in strutil.cc
  41. #elif defined(HAVE_PTHREAD)
  42. #include <pthread.h>
  43. #else
  44. #error "No suitable threading library available."
  45. #endif
  46. namespace google {
  47. namespace protobuf {
  48. namespace internal {
  49. void VerifyVersion(int headerVersion,
  50. int minLibraryVersion,
  51. const char* filename) {
  52. if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
  53. // Library is too old for headers.
  54. GOOGLE_LOG(FATAL)
  55. << "This program requires version " << VersionString(minLibraryVersion)
  56. << " of the Protocol Buffer runtime library, but the installed version "
  57. "is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update "
  58. "your library. If you compiled the program yourself, make sure that "
  59. "your headers are from the same version of Protocol Buffers as your "
  60. "link-time library. (Version verification failed in \""
  61. << filename << "\".)";
  62. }
  63. if (headerVersion < kMinHeaderVersionForLibrary) {
  64. // Headers are too old for library.
  65. GOOGLE_LOG(FATAL)
  66. << "This program was compiled against version "
  67. << VersionString(headerVersion) << " of the Protocol Buffer runtime "
  68. "library, which is not compatible with the installed version ("
  69. << VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program "
  70. "author for an update. If you compiled the program yourself, make "
  71. "sure that your headers are from the same version of Protocol Buffers "
  72. "as your link-time library. (Version verification failed in \""
  73. << filename << "\".)";
  74. }
  75. }
  76. string VersionString(int version) {
  77. int major = version / 1000000;
  78. int minor = (version / 1000) % 1000;
  79. int micro = version % 1000;
  80. // 128 bytes should always be enough, but we use snprintf() anyway to be
  81. // safe.
  82. char buffer[128];
  83. snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
  84. // Guard against broken MSVC snprintf().
  85. buffer[sizeof(buffer)-1] = '\0';
  86. return buffer;
  87. }
  88. } // namespace internal
  89. // ===================================================================
  90. // emulates google3/base/logging.cc
  91. namespace internal {
  92. void DefaultLogHandler(LogLevel level, const char* filename, int line,
  93. const string& message) {
  94. static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
  95. // We use fprintf() instead of cerr because we want this to work at static
  96. // initialization time.
  97. fprintf(stderr, "libprotobuf %s %s:%d] %s\n",
  98. level_names[level], filename, line, message.c_str());
  99. fflush(stderr); // Needed on MSVC.
  100. }
  101. void NullLogHandler(LogLevel level, const char* filename, int line,
  102. const string& message) {
  103. // Nothing.
  104. }
  105. static LogHandler* log_handler_ = &DefaultLogHandler;
  106. static int log_silencer_count_ = 0;
  107. static Mutex* log_silencer_count_mutex_ = NULL;
  108. GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
  109. void DeleteLogSilencerCount() {
  110. delete log_silencer_count_mutex_;
  111. log_silencer_count_mutex_ = NULL;
  112. }
  113. void InitLogSilencerCount() {
  114. log_silencer_count_mutex_ = new Mutex;
  115. OnShutdown(&DeleteLogSilencerCount);
  116. }
  117. void InitLogSilencerCountOnce() {
  118. GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
  119. }
  120. LogMessage& LogMessage::operator<<(const string& value) {
  121. message_ += value;
  122. return *this;
  123. }
  124. LogMessage& LogMessage::operator<<(const char* value) {
  125. message_ += value;
  126. return *this;
  127. }
  128. // Since this is just for logging, we don't care if the current locale changes
  129. // the results -- in fact, we probably prefer that. So we use snprintf()
  130. // instead of Simple*toa().
  131. #undef DECLARE_STREAM_OPERATOR
  132. #define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \
  133. LogMessage& LogMessage::operator<<(TYPE value) { \
  134. /* 128 bytes should be big enough for any of the primitive */ \
  135. /* values which we print with this, but well use snprintf() */ \
  136. /* anyway to be extra safe. */ \
  137. char buffer[128]; \
  138. snprintf(buffer, sizeof(buffer), FORMAT, value); \
  139. /* Guard against broken MSVC snprintf(). */ \
  140. buffer[sizeof(buffer)-1] = '\0'; \
  141. message_ += buffer; \
  142. return *this; \
  143. }
  144. DECLARE_STREAM_OPERATOR(char , "%c" )
  145. DECLARE_STREAM_OPERATOR(int , "%d" )
  146. DECLARE_STREAM_OPERATOR(uint , "%u" )
  147. DECLARE_STREAM_OPERATOR(long , "%ld")
  148. DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
  149. DECLARE_STREAM_OPERATOR(double , "%g" )
  150. #undef DECLARE_STREAM_OPERATOR
  151. LogMessage::LogMessage(LogLevel level, const char* filename, int line)
  152. : level_(level), filename_(filename), line_(line) {}
  153. LogMessage::~LogMessage() {}
  154. void LogMessage::Finish() {
  155. bool suppress = false;
  156. if (level_ != LOGLEVEL_FATAL) {
  157. InitLogSilencerCountOnce();
  158. MutexLock lock(log_silencer_count_mutex_);
  159. suppress = internal::log_silencer_count_ > 0;
  160. }
  161. if (!suppress) {
  162. internal::log_handler_(level_, filename_, line_, message_);
  163. }
  164. if (level_ == LOGLEVEL_FATAL) {
  165. #ifdef PROTOBUF_USE_EXCEPTIONS
  166. throw FatalException(filename_, line_, message_);
  167. #else
  168. abort();
  169. #endif
  170. }
  171. }
  172. void LogFinisher::operator=(LogMessage& other) {
  173. other.Finish();
  174. }
  175. } // namespace internal
  176. LogHandler* SetLogHandler(LogHandler* new_func) {
  177. LogHandler* old = internal::log_handler_;
  178. if (old == &internal::NullLogHandler) {
  179. old = NULL;
  180. }
  181. if (new_func == NULL) {
  182. internal::log_handler_ = &internal::NullLogHandler;
  183. } else {
  184. internal::log_handler_ = new_func;
  185. }
  186. return old;
  187. }
  188. LogSilencer::LogSilencer() {
  189. internal::InitLogSilencerCountOnce();
  190. MutexLock lock(internal::log_silencer_count_mutex_);
  191. ++internal::log_silencer_count_;
  192. };
  193. LogSilencer::~LogSilencer() {
  194. internal::InitLogSilencerCountOnce();
  195. MutexLock lock(internal::log_silencer_count_mutex_);
  196. --internal::log_silencer_count_;
  197. };
  198. // ===================================================================
  199. // emulates google3/base/callback.cc
  200. Closure::~Closure() {}
  201. namespace internal { FunctionClosure0::~FunctionClosure0() {} }
  202. void DoNothing() {}
  203. // ===================================================================
  204. // emulates google3/base/mutex.cc
  205. #ifdef _WIN32
  206. struct Mutex::Internal {
  207. CRITICAL_SECTION mutex;
  208. #ifndef NDEBUG
  209. // Used only to implement AssertHeld().
  210. DWORD thread_id;
  211. #endif
  212. };
  213. Mutex::Mutex()
  214. : mInternal(new Internal) {
  215. InitializeCriticalSection(&mInternal->mutex);
  216. }
  217. Mutex::~Mutex() {
  218. DeleteCriticalSection(&mInternal->mutex);
  219. delete mInternal;
  220. }
  221. void Mutex::Lock() {
  222. EnterCriticalSection(&mInternal->mutex);
  223. #ifndef NDEBUG
  224. mInternal->thread_id = GetCurrentThreadId();
  225. #endif
  226. }
  227. void Mutex::Unlock() {
  228. #ifndef NDEBUG
  229. mInternal->thread_id = 0;
  230. #endif
  231. LeaveCriticalSection(&mInternal->mutex);
  232. }
  233. void Mutex::AssertHeld() {
  234. #ifndef NDEBUG
  235. GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
  236. #endif
  237. }
  238. #elif defined(HAVE_PTHREAD)
  239. struct Mutex::Internal {
  240. pthread_mutex_t mutex;
  241. };
  242. Mutex::Mutex()
  243. : mInternal(new Internal) {
  244. pthread_mutex_init(&mInternal->mutex, NULL);
  245. }
  246. Mutex::~Mutex() {
  247. pthread_mutex_destroy(&mInternal->mutex);
  248. delete mInternal;
  249. }
  250. void Mutex::Lock() {
  251. int result = pthread_mutex_lock(&mInternal->mutex);
  252. if (result != 0) {
  253. GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
  254. }
  255. }
  256. void Mutex::Unlock() {
  257. int result = pthread_mutex_unlock(&mInternal->mutex);
  258. if (result != 0) {
  259. GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
  260. }
  261. }
  262. void Mutex::AssertHeld() {
  263. // pthreads dosn't provide a way to check which thread holds the mutex.
  264. // TODO(kenton): Maybe keep track of locking thread ID like with WIN32?
  265. }
  266. #endif
  267. // ===================================================================
  268. // Shutdown support.
  269. namespace internal {
  270. typedef void OnShutdownFunc();
  271. vector<void (*)()>* shutdown_functions = NULL;
  272. Mutex* shutdown_functions_mutex = NULL;
  273. GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
  274. void InitShutdownFunctions() {
  275. shutdown_functions = new vector<void (*)()>;
  276. shutdown_functions_mutex = new Mutex;
  277. }
  278. inline void InitShutdownFunctionsOnce() {
  279. GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
  280. }
  281. void OnShutdown(void (*func)()) {
  282. InitShutdownFunctionsOnce();
  283. MutexLock lock(shutdown_functions_mutex);
  284. shutdown_functions->push_back(func);
  285. }
  286. } // namespace internal
  287. void ShutdownProtobufLibrary() {
  288. internal::InitShutdownFunctionsOnce();
  289. // We don't need to lock shutdown_functions_mutex because it's up to the
  290. // caller to make sure that no one is using the library before this is
  291. // called.
  292. // Make it safe to call this multiple times.
  293. if (internal::shutdown_functions == NULL) return;
  294. for (int i = 0; i < internal::shutdown_functions->size(); i++) {
  295. internal::shutdown_functions->at(i)();
  296. }
  297. delete internal::shutdown_functions;
  298. internal::shutdown_functions = NULL;
  299. delete internal::shutdown_functions_mutex;
  300. internal::shutdown_functions_mutex = NULL;
  301. }
  302. #ifdef PROTOBUF_USE_EXCEPTIONS
  303. FatalException::~FatalException() throw() {}
  304. const char* FatalException::what() const throw() {
  305. return message_.c_str();
  306. }
  307. #endif
  308. } // namespace protobuf
  309. } // namespace google