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 39namespace media { 40 41namespace { 42 43// Helper functions to wrap platform differences. 44 45int32 CurrentProcessId() { 46#if defined(OS_WIN) 47 return GetCurrentProcessId(); 48#elif defined(OS_POSIX) 49 return getpid(); 50#endif 51} 52 53int32 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 69uint64 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 88CdmLogMessage::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 123CdmLogMessage::~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