Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 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 #include "base/tracked.h"
      6 
      7 #include "base/stringprintf.h"
      8 #include "base/tracked_objects.h"
      9 
     10 using base::TimeTicks;
     11 
     12 namespace tracked_objects {
     13 
     14 //------------------------------------------------------------------------------
     15 
     16 Location::Location(const char* function_name, const char* file_name,
     17                    int line_number)
     18     : function_name_(function_name),
     19       file_name_(file_name),
     20       line_number_(line_number) {
     21 }
     22 
     23 Location::Location()
     24     : function_name_("Unknown"),
     25       file_name_("Unknown"),
     26       line_number_(-1) {
     27 }
     28 
     29 void Location::Write(bool display_filename, bool display_function_name,
     30                      std::string* output) const {
     31   base::StringAppendF(output, "%s[%d] ",
     32       display_filename ? file_name_ : "line",
     33       line_number_);
     34 
     35   if (display_function_name) {
     36     WriteFunctionName(output);
     37     output->push_back(' ');
     38   }
     39 }
     40 
     41 void Location::WriteFunctionName(std::string* output) const {
     42   // Translate "<" to "&lt;" for HTML safety.
     43   // TODO(jar): Support ASCII or html for logging in ASCII.
     44   for (const char *p = function_name_; *p; p++) {
     45     switch (*p) {
     46       case '<':
     47         output->append("&lt;");
     48         break;
     49 
     50       case '>':
     51         output->append("&gt;");
     52         break;
     53 
     54       default:
     55         output->push_back(*p);
     56         break;
     57     }
     58   }
     59 }
     60 
     61 //------------------------------------------------------------------------------
     62 
     63 #ifndef TRACK_ALL_TASK_OBJECTS
     64 
     65 Tracked::Tracked() {}
     66 Tracked::~Tracked() {}
     67 void Tracked::SetBirthPlace(const Location& from_here) {}
     68 const Location Tracked::GetBirthPlace() const {
     69   static Location kNone("NoFunctionName", "NeedToSetBirthPlace", -1);
     70   return kNone;
     71 }
     72 bool Tracked::MissingBirthplace() const { return false; }
     73 void Tracked::ResetBirthTime() {}
     74 
     75 #else
     76 
     77 Tracked::Tracked()
     78     : tracked_births_(NULL),
     79       tracked_birth_time_(TimeTicks::Now()) {
     80   if (!ThreadData::IsActive())
     81     return;
     82   SetBirthPlace(Location("NoFunctionName", "NeedToSetBirthPlace", -1));
     83 }
     84 
     85 Tracked::~Tracked() {
     86   if (!ThreadData::IsActive() || !tracked_births_)
     87     return;
     88   ThreadData::current()->TallyADeath(*tracked_births_,
     89                                      TimeTicks::Now() - tracked_birth_time_);
     90 }
     91 
     92 void Tracked::SetBirthPlace(const Location& from_here) {
     93   if (!ThreadData::IsActive())
     94     return;
     95   if (tracked_births_)
     96     tracked_births_->ForgetBirth();
     97   ThreadData* current_thread_data = ThreadData::current();
     98   if (!current_thread_data)
     99     return;  // Shutdown started, and this thread wasn't registered.
    100   tracked_births_ = current_thread_data->TallyABirth(from_here);
    101 }
    102 
    103 const Location Tracked::GetBirthPlace() const {
    104   return tracked_births_->location();
    105 }
    106 
    107 void Tracked::ResetBirthTime() {
    108   tracked_birth_time_ = TimeTicks::Now();
    109 }
    110 
    111 bool Tracked::MissingBirthplace() const {
    112   return -1 == tracked_births_->location().line_number();
    113 }
    114 
    115 #endif  // NDEBUG
    116 
    117 }  // namespace tracked_objects
    118