15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Only compile this file in debug build. This gives us one more level of
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// protection that if the linker tries to link in strings/symbols appended to
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// "DLOG() <<" in release build (which it shouldn't), we'll get "undefined
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// reference" errors.
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(NDEBUG)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cdm/ppapi/cdm_logging.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <io.h>
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <windows.h>
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_MACOSX)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <mach/mach.h>
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <mach/mach_time.h>
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <mach-o/dyld.h>
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_POSIX)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sys/syscall.h>
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <time.h>
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_POSIX)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <errno.h>
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <pthread.h>
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdlib.h>
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdio.h>
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string.h>
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <unistd.h>
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <iomanip>
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string>
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace media {
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Helper functions to wrap platform differences.
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int32 CurrentProcessId() {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GetCurrentProcessId();
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_POSIX)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return getpid();
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int32 CurrentThreadId() {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Pthreads doesn't have the concept of a thread ID, so we have to reach down
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // into the kernel.
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return syscall(__NR_gettid);
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_ANDROID)
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return gettid();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_SOLARIS)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return pthread_self();
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_POSIX)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return reinterpret_cast<int64>(pthread_self());
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_WIN)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return static_cast<int32>(::GetCurrentThreadId());
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint64 TickCount() {
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return GetTickCount();
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_MACOSX)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return mach_absolute_time();
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_POSIX)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct timespec ts;
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  clock_gettime(CLOCK_MONOTONIC, &ts);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint64 absolute_micro =
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    static_cast<int64>(ts.tv_sec) * 1000000 +
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    static_cast<int64>(ts.tv_nsec) / 1000;
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return absolute_micro;
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CdmLogMessage::CdmLogMessage(const char* file, int line) {
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string filename(file);
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t last_slash_pos = filename.find_last_of("\\/");
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (last_slash_pos != std::string::npos)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    filename = filename.substr(last_slash_pos + 1);
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_ << '[';
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Process and thread ID.
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_ << CurrentProcessId() << ':';
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_ << CurrentThreadId() << ':';
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Time and tick count.
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  time_t t = time(NULL);
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct tm local_time = {0};
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if _MSC_VER >= 1400
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  localtime_s(&local_time, &t);
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  localtime_r(&t, &local_time);
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct tm* tm_time = &local_time;
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_ << std::setfill('0')
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << std::setw(2) << 1 + tm_time->tm_mon
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << std::setw(2) << tm_time->tm_mday
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << '/'
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << std::setw(2) << tm_time->tm_hour
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << std::setw(2) << tm_time->tm_min
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << std::setw(2) << tm_time->tm_sec
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          << ':';
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_ << TickCount() << ':';
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // File name.
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream_ << filename << "(" << line << ")] ";
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CdmLogMessage::~CdmLogMessage() {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Use std::cout explicitly for the line break. This limits the use of this
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // class only to the definition of DLOG() (which also uses std::cout).
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This appends "std::endl" after all other messages appended to DLOG(),
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // which relies on the C++ standard ISO/IEC 14882:1998(E) $12.2.3:
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // "Temporary objects are destroyed as the last step in evaluating the
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // full-expression (1.9) that (lexically) contains the point where they were
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // created."
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::cout << std::endl;
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace media
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // !defined(NDEBUG)
138