Home | History | Annotate | Download | only in ppapi
      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