1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Only compile this file in debug build. This gives us one more level of 6 // protection that if the linker tries to link in strings/symbols appended to 7 // "DLOG() <<" in release build (which it shouldn't), we'll get "undefined 8 // reference" errors. 9 #if !defined(NDEBUG) 10 11 #include "media/cdm/ppapi/cdm_logging.h" 12 13 #include "base/basictypes.h" 14 15 #if defined(OS_WIN) 16 #include <io.h> 17 #include <windows.h> 18 #elif defined(OS_MACOSX) 19 #include <mach/mach.h> 20 #include <mach/mach_time.h> 21 #include <mach-o/dyld.h> 22 #elif defined(OS_POSIX) 23 #include <sys/syscall.h> 24 #include <time.h> 25 #endif 26 27 #if defined(OS_POSIX) 28 #include <errno.h> 29 #include <pthread.h> 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <unistd.h> 34 #endif 35 36 #include <iomanip> 37 #include <string> 38 39 namespace media { 40 41 namespace { 42 43 // Helper functions to wrap platform differences. 44 45 int32 CurrentProcessId() { 46 #if defined(OS_WIN) 47 return GetCurrentProcessId(); 48 #elif defined(OS_POSIX) 49 return getpid(); 50 #endif 51 } 52 53 int32 CurrentThreadId() { 54 // Pthreads doesn't have the concept of a thread ID, so we have to reach down 55 // into the kernel. 56 #if defined(OS_LINUX) 57 return syscall(__NR_gettid); 58 #elif defined(OS_ANDROID) 59 return gettid(); 60 #elif defined(OS_SOLARIS) 61 return pthread_self(); 62 #elif defined(OS_POSIX) 63 return reinterpret_cast<int64>(pthread_self()); 64 #elif defined(OS_WIN) 65 return static_cast<int32>(::GetCurrentThreadId()); 66 #endif 67 } 68 69 uint64 TickCount() { 70 #if defined(OS_WIN) 71 return GetTickCount(); 72 #elif defined(OS_MACOSX) 73 return mach_absolute_time(); 74 #elif defined(OS_POSIX) 75 struct timespec ts; 76 clock_gettime(CLOCK_MONOTONIC, &ts); 77 78 uint64 absolute_micro = 79 static_cast<int64>(ts.tv_sec) * 1000000 + 80 static_cast<int64>(ts.tv_nsec) / 1000; 81 82 return absolute_micro; 83 #endif 84 } 85 86 } // namespace 87 88 CdmLogMessage::CdmLogMessage(const char* file, int line) { 89 std::string filename(file); 90 size_t last_slash_pos = filename.find_last_of("\\/"); 91 if (last_slash_pos != std::string::npos) 92 filename = filename.substr(last_slash_pos + 1); 93 94 stream_ << '['; 95 96 // Process and thread ID. 97 stream_ << CurrentProcessId() << ':'; 98 stream_ << CurrentThreadId() << ':'; 99 100 // Time and tick count. 101 time_t t = time(NULL); 102 struct tm local_time = {0}; 103 #if _MSC_VER >= 1400 104 localtime_s(&local_time, &t); 105 #else 106 localtime_r(&t, &local_time); 107 #endif 108 struct tm* tm_time = &local_time; 109 stream_ << std::setfill('0') 110 << std::setw(2) << 1 + tm_time->tm_mon 111 << std::setw(2) << tm_time->tm_mday 112 << '/' 113 << std::setw(2) << tm_time->tm_hour 114 << std::setw(2) << tm_time->tm_min 115 << std::setw(2) << tm_time->tm_sec 116 << ':'; 117 stream_ << TickCount() << ':'; 118 119 // File name. 120 stream_ << filename << "(" << line << ")] "; 121 } 122 123 CdmLogMessage::~CdmLogMessage() { 124 // Use std::cout explicitly for the line break. This limits the use of this 125 // class only to the definition of DLOG() (which also uses std::cout). 126 // 127 // This appends "std::endl" after all other messages appended to DLOG(), 128 // which relies on the C++ standard ISO/IEC 14882:1998(E) $12.2.3: 129 // "Temporary objects are destroyed as the last step in evaluating the 130 // full-expression (1.9) that (lexically) contains the point where they were 131 // created." 132 std::cout << std::endl; 133 } 134 135 } // namespace media 136 137 #endif // !defined(NDEBUG) 138