Index: chrome/browser/metrics/tracking_synchronizer.cc |
diff --git a/chrome/browser/metrics/tracking_synchronizer.cc b/chrome/browser/metrics/tracking_synchronizer.cc |
index e64b9240883e4be90e228456d9941eb24f49bf0b..635e0fde7e0e813fb9f03e2775cba3fe5e7702de 100644 |
--- a/chrome/browser/metrics/tracking_synchronizer.cc |
+++ b/chrome/browser/metrics/tracking_synchronizer.cc |
@@ -9,31 +9,50 @@ |
#include "base/process_util.h" |
#include "base/threading/thread.h" |
#include "base/tracked_objects.h" |
+#include "chrome/browser/metrics/tracking_synchronizer_observer.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/profiler_controller.h" |
-#include "content/public/common/process_type.h" |
using base::TimeTicks; |
using content::BrowserThread; |
+namespace { |
+ |
+// Negative numbers are never used as sequence numbers. We explicitly pick a |
+// negative number that is "so negative" that even when we add one (as is done |
+// when we generated the next sequence number) that it will still be negative. |
+// We have code that handles wrapping around on an overflow into negative |
+// territory. |
+const int kNeverUsableSequenceNumber = -2; |
+ |
+// This singleton instance should be started during the single threaded |
+// portion of main(). It initializes globals to provide support for all future |
+// calls. This object is created on the UI thread, and it is destroyed after |
+// all the other threads have gone away. As a result, it is ok to call it |
+// from the UI thread, or for about:profiler. |
+static chrome_browser_metrics::TrackingSynchronizer* g_tracking_synchronizer = |
+ NULL; |
+ |
+} // anonymous namespace |
+ |
namespace chrome_browser_metrics { |
// The "RequestContext" structure describes an individual request received |
// from the UI. All methods are accessible on UI thread. |
-class RequestContext { |
+class TrackingSynchronizer::RequestContext { |
public: |
// A map from sequence_number_ to the actual RequestContexts. |
typedef std::map<int, RequestContext*> RequestContextMap; |
- ~RequestContext() {} |
- |
- RequestContext(const base::WeakPtr<ProfilerUI>& callback_object, |
- int sequence_number) |
+ RequestContext( |
+ const base::WeakPtr<TrackingSynchronizerObserver>& callback_object, |
+ int sequence_number) |
: callback_object_(callback_object), |
sequence_number_(sequence_number), |
received_process_group_count_(0), |
processes_pending_(0) { |
} |
+ ~RequestContext() {} |
void SetReceivedProcessGroupCount(bool done) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
@@ -63,9 +82,8 @@ class RequestContext { |
void DeleteIfAllDone() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (processes_pending_ <= 0 && received_process_group_count_) { |
+ if (processes_pending_ <= 0 && received_process_group_count_) |
RequestContext::Unregister(sequence_number_); |
- } |
} |
@@ -73,7 +91,7 @@ class RequestContext { |
// |sequence_number|. |
static RequestContext* Register( |
int sequence_number, |
- const base::WeakPtr<ProfilerUI>& callback_object) { |
+ const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
RequestContext* request = new RequestContext( |
@@ -93,9 +111,8 @@ class RequestContext { |
if (it == outstanding_requests_.Get().end()) |
return NULL; |
- RequestContext* request = NULL; |
- request = it->second; |
- DCHECK(sequence_number == request->sequence_number_); |
+ RequestContext* request = it->second; |
+ DCHECK_EQ(sequence_number, request->sequence_number_); |
return request; |
} |
@@ -111,11 +128,13 @@ class RequestContext { |
return; |
RequestContext* request = it->second; |
- DCHECK(sequence_number == request->sequence_number_); |
+ DCHECK_EQ(sequence_number, request->sequence_number_); |
bool received_process_group_count = request->received_process_group_count_; |
int unresponsive_processes = request->processes_pending_; |
- delete it->second; |
+ request->callback_object_->FinishedReceivingProfilerData(); |
+ |
+ delete request; |
outstanding_requests_.Get().erase(it); |
UMA_HISTOGRAM_BOOLEAN("Profiling.ReceivedProcessGroupCount", |
@@ -136,7 +155,7 @@ class RequestContext { |
} |
// Requests are made to asynchronously send data to the |callback_object_|. |
- base::WeakPtr<ProfilerUI> callback_object_; |
+ base::WeakPtr<TrackingSynchronizerObserver> callback_object_; |
// The sequence number used by the most recent update request to contact all |
// processes. |
@@ -154,22 +173,17 @@ class RequestContext { |
static base::LazyInstance<RequestContextMap> outstanding_requests_; |
}; |
-// Negative numbers are never used as sequence numbers. We explicitly pick a |
-// negative number that is "so negative" that even when we add one (as is done |
-// when we generated the next sequence number) that it will still be negative. |
-// We have code that handles wrapping around on an overflow into negative |
-// territory. |
-static const int kNeverUsableSequenceNumber = -2; |
+// static |
+base::LazyInstance<TrackingSynchronizer::RequestContext::RequestContextMap> |
+ TrackingSynchronizer::RequestContext::outstanding_requests_ = |
+ LAZY_INSTANCE_INITIALIZER; |
// TrackingSynchronizer methods and members. |
-// |
-// static |
-TrackingSynchronizer* TrackingSynchronizer::tracking_synchronizer_ = NULL; |
TrackingSynchronizer::TrackingSynchronizer() |
: last_used_sequence_number_(kNeverUsableSequenceNumber) { |
- DCHECK(tracking_synchronizer_ == NULL); |
- tracking_synchronizer_ = this; |
+ DCHECK(!g_tracking_synchronizer); |
+ g_tracking_synchronizer = this; |
content::ProfilerController::GetInstance()->Register(this); |
} |
@@ -179,21 +193,20 @@ TrackingSynchronizer::~TrackingSynchronizer() { |
// Just in case we have any pending tasks, clear them out. |
RequestContext::OnShutdown(); |
- tracking_synchronizer_ = NULL; |
+ g_tracking_synchronizer = NULL; |
} |
// static |
void TrackingSynchronizer::FetchProfilerDataAsynchronously( |
- const base::WeakPtr<ProfilerUI>& callback_object) { |
+ const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- TrackingSynchronizer* current_synchronizer = CurrentSynchronizer(); |
- if (current_synchronizer == NULL) { |
+ if (!g_tracking_synchronizer) { |
// System teardown is happening. |
return; |
} |
- int sequence_number = current_synchronizer->RegisterAndNotifyAllProcesses( |
+ int sequence_number = g_tracking_synchronizer->RegisterAndNotifyAllProcesses( |
callback_object); |
// Post a task that would be called after waiting for wait_time. This acts |
@@ -219,24 +232,21 @@ void TrackingSynchronizer::OnPendingProcesses(int sequence_number, |
void TrackingSynchronizer::OnProfilerDataCollected( |
int sequence_number, |
- base::DictionaryValue* profiler_data) { |
+ const tracked_objects::ProcessDataSnapshot& profiler_data, |
+ content::ProcessType process_type) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- |
- RequestContext* request = RequestContext::GetRequestContext(sequence_number); |
- if (!request) |
- return; |
- |
- DecrementPendingProcessesAndSendData(sequence_number, profiler_data); |
+ DecrementPendingProcessesAndSendData(sequence_number, profiler_data, |
+ process_type); |
} |
int TrackingSynchronizer::RegisterAndNotifyAllProcesses( |
- const base::WeakPtr<ProfilerUI>& callback_object) { |
+ const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
int sequence_number = GetNextAvailableSequenceNumber(); |
RequestContext* request = |
- RequestContext::Register(sequence_number, callback_object); |
+ RequestContext::Register(sequence_number, callback_object); |
// Increment pending process count for sending browser's profiler data. |
request->IncrementProcessesPending(); |
@@ -245,32 +255,27 @@ int TrackingSynchronizer::RegisterAndNotifyAllProcesses( |
content::ProfilerController::GetInstance()->GetProfilerData(sequence_number); |
// Send profiler_data from browser process. |
- base::DictionaryValue* value = tracked_objects::ThreadData::ToValue(false); |
- const std::string process_type = |
- content::GetProcessTypeNameInEnglish(content::PROCESS_TYPE_BROWSER); |
- value->SetString("process_type", process_type); |
- value->SetInteger("process_id", base::GetCurrentProcId()); |
- DecrementPendingProcessesAndSendData(sequence_number, value); |
+ tracked_objects::ProcessDataSnapshot process_data; |
+ tracked_objects::ThreadData::Snapshot(false, &process_data); |
+ DecrementPendingProcessesAndSendData(sequence_number, process_data, |
+ content::PROCESS_TYPE_BROWSER); |
return sequence_number; |
} |
void TrackingSynchronizer::DecrementPendingProcessesAndSendData( |
int sequence_number, |
- base::DictionaryValue* value) { |
+ const tracked_objects::ProcessDataSnapshot& profiler_data, |
+ content::ProcessType process_type) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
RequestContext* request = RequestContext::GetRequestContext(sequence_number); |
- if (!request) { |
- delete value; |
+ if (!request) |
return; |
- } |
- if (value && request->callback_object_) { |
- // Transfers ownership of |value| to |callback_object_|. |
- request->callback_object_->ReceivedData(value); |
- } else { |
- delete value; |
+ if (request->callback_object_) { |
+ request->callback_object_->ReceivedProfilerData(profiler_data, |
+ process_type); |
} |
// Delete request if we have heard back from all child processes. |
@@ -289,15 +294,4 @@ int TrackingSynchronizer::GetNextAvailableSequenceNumber() { |
return last_used_sequence_number_; |
} |
-// static |
-TrackingSynchronizer* TrackingSynchronizer::CurrentSynchronizer() { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- DCHECK(tracking_synchronizer_ != NULL); |
- return tracking_synchronizer_; |
-} |
- |
-// static |
-base::LazyInstance<RequestContext::RequestContextMap> |
- RequestContext::outstanding_requests_ = LAZY_INSTANCE_INITIALIZER; |
- |
} // namespace chrome_browser_metrics |