PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/external/protobuf/src/google/protobuf/stubs/common.cc

https://gitlab.com/brian0218/rk3066_r-box_android4.2.2_sdk
C++ | 365 lines | 243 code | 66 blank | 56 comment | 19 complexity | 31d3a4d77054a2249b4972a1e358363e 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. abort();
  166. }
  167. }
  168. void LogFinisher::operator=(LogMessage& other) {
  169. other.Finish();
  170. }
  171. } // namespace internal
  172. LogHandler* SetLogHandler(LogHandler* new_func) {
  173. LogHandler* old = internal::log_handler_;
  174. if (old == &internal::NullLogHandler) {
  175. old = NULL;
  176. }
  177. if (new_func == NULL) {
  178. internal::log_handler_ = &internal::NullLogHandler;
  179. } else {
  180. internal::log_handler_ = new_func;
  181. }
  182. return old;
  183. }
  184. LogSilencer::LogSilencer() {
  185. internal::InitLogSilencerCountOnce();
  186. MutexLock lock(internal::log_silencer_count_mutex_);
  187. ++internal::log_silencer_count_;
  188. };
  189. LogSilencer::~LogSilencer() {
  190. internal::InitLogSilencerCountOnce();
  191. MutexLock lock(internal::log_silencer_count_mutex_);
  192. --internal::log_silencer_count_;
  193. };
  194. // ===================================================================
  195. // emulates google3/base/callback.cc
  196. Closure::~Closure() {}
  197. namespace internal { FunctionClosure0::~FunctionClosure0() {} }
  198. void DoNothing() {}
  199. // ===================================================================
  200. // emulates google3/base/mutex.cc
  201. #ifdef _WIN32
  202. struct Mutex::Internal {
  203. CRITICAL_SECTION mutex;
  204. #ifndef NDEBUG
  205. // Used only to implement AssertHeld().
  206. DWORD thread_id;
  207. #endif
  208. };
  209. Mutex::Mutex()
  210. : mInternal(new Internal) {
  211. InitializeCriticalSection(&mInternal->mutex);
  212. }
  213. Mutex::~Mutex() {
  214. DeleteCriticalSection(&mInternal->mutex);
  215. delete mInternal;
  216. }
  217. void Mutex::Lock() {
  218. EnterCriticalSection(&mInternal->mutex);
  219. #ifndef NDEBUG
  220. mInternal->thread_id = GetCurrentThreadId();
  221. #endif
  222. }
  223. void Mutex::Unlock() {
  224. #ifndef NDEBUG
  225. mInternal->thread_id = 0;
  226. #endif
  227. LeaveCriticalSection(&mInternal->mutex);
  228. }
  229. void Mutex::AssertHeld() {
  230. #ifndef NDEBUG
  231. GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
  232. #endif
  233. }
  234. #elif defined(HAVE_PTHREAD)
  235. struct Mutex::Internal {
  236. pthread_mutex_t mutex;
  237. };
  238. Mutex::Mutex()
  239. : mInternal(new Internal) {
  240. pthread_mutex_init(&mInternal->mutex, NULL);
  241. }
  242. Mutex::~Mutex() {
  243. pthread_mutex_destroy(&mInternal->mutex);
  244. delete mInternal;
  245. }
  246. void Mutex::Lock() {
  247. int result = pthread_mutex_lock(&mInternal->mutex);
  248. if (result != 0) {
  249. GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
  250. }
  251. }
  252. void Mutex::Unlock() {
  253. int result = pthread_mutex_unlock(&mInternal->mutex);
  254. if (result != 0) {
  255. GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
  256. }
  257. }
  258. void Mutex::AssertHeld() {
  259. // pthreads dosn't provide a way to check which thread holds the mutex.
  260. // TODO(kenton): Maybe keep track of locking thread ID like with WIN32?
  261. }
  262. #endif
  263. // ===================================================================
  264. // Shutdown support.
  265. namespace internal {
  266. typedef void OnShutdownFunc();
  267. vector<void (*)()>* shutdown_functions = NULL;
  268. Mutex* shutdown_functions_mutex = NULL;
  269. GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
  270. void InitShutdownFunctions() {
  271. shutdown_functions = new vector<void (*)()>;
  272. shutdown_functions_mutex = new Mutex;
  273. }
  274. inline void InitShutdownFunctionsOnce() {
  275. GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
  276. }
  277. void OnShutdown(void (*func)()) {
  278. InitShutdownFunctionsOnce();
  279. MutexLock lock(shutdown_functions_mutex);
  280. shutdown_functions->push_back(func);
  281. }
  282. } // namespace internal
  283. void ShutdownProtobufLibrary() {
  284. internal::InitShutdownFunctionsOnce();
  285. // We don't need to lock shutdown_functions_mutex because it's up to the
  286. // caller to make sure that no one is using the library before this is
  287. // called.
  288. // Make it safe to call this multiple times.
  289. if (internal::shutdown_functions == NULL) return;
  290. for (int i = 0; i < internal::shutdown_functions->size(); i++) {
  291. internal::shutdown_functions->at(i)();
  292. }
  293. delete internal::shutdown_functions;
  294. internal::shutdown_functions = NULL;
  295. delete internal::shutdown_functions_mutex;
  296. internal::shutdown_functions_mutex = NULL;
  297. }
  298. } // namespace protobuf
  299. } // namespace google