cdm_logging.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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