OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/metrics/tracking_synchronizer.h" | 5 #include "chrome/browser/metrics/tracking_synchronizer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/process_util.h" | 9 #include "base/process_util.h" |
10 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 // the given sequence number. If |received_process_group_count_| and | 79 // the given sequence number. If |received_process_group_count_| and |
80 // |processes_pending_| are zero, then delete the current object by calling | 80 // |processes_pending_| are zero, then delete the current object by calling |
81 // Unregister. | 81 // Unregister. |
82 void DeleteIfAllDone() { | 82 void DeleteIfAllDone() { |
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
84 | 84 |
85 if (processes_pending_ <= 0 && received_process_group_count_) | 85 if (processes_pending_ <= 0 && received_process_group_count_) |
86 RequestContext::Unregister(sequence_number_); | 86 RequestContext::Unregister(sequence_number_); |
87 } | 87 } |
88 | 88 |
89 | |
90 // Register |callback_object| in |outstanding_requests_| map for the given | 89 // Register |callback_object| in |outstanding_requests_| map for the given |
91 // |sequence_number|. | 90 // |sequence_number|. |
92 static RequestContext* Register( | 91 static RequestContext* Register( |
93 int sequence_number, | 92 int sequence_number, |
94 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) { | 93 const base::WeakPtr<TrackingSynchronizerObserver>& callback_object) { |
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
96 | 95 |
97 RequestContext* request = new RequestContext( | 96 RequestContext* request = new RequestContext( |
98 callback_object, sequence_number); | 97 callback_object, sequence_number); |
99 outstanding_requests_.Get()[sequence_number] = request; | 98 outstanding_requests_.Get()[sequence_number] = request; |
100 | 99 |
101 return request; | 100 return request; |
102 } | 101 } |
103 | 102 |
104 // Find the |RequestContext| in |outstanding_requests_| map for the given | 103 // Find the |RequestContext| in |outstanding_requests_| map for the given |
105 // |sequence_number|. | 104 // |sequence_number|. |
106 static RequestContext* GetRequestContext(int sequence_number) { | 105 static RequestContext* GetRequestContext(int sequence_number) { |
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
108 | 107 |
109 RequestContextMap::iterator it = | 108 RequestContextMap::iterator it = |
110 outstanding_requests_.Get().find(sequence_number); | 109 outstanding_requests_.Get().find(sequence_number); |
111 if (it == outstanding_requests_.Get().end()) | 110 if (it == outstanding_requests_.Get().end()) |
112 return NULL; | 111 return NULL; |
113 | 112 |
114 RequestContext* request = it->second; | 113 RequestContext* request = it->second; |
115 DCHECK_EQ(sequence_number, request->sequence_number_); | 114 DCHECK_EQ(sequence_number, request->sequence_number_); |
116 return request; | 115 return request; |
117 } | 116 } |
118 | 117 |
119 // Delete the entry for the given sequence_number| from | 118 // Delete the entry for the given |sequence_number| from |
120 // |outstanding_requests_| map. This method is called when all changes have | 119 // |outstanding_requests_| map. This method is called when all changes have |
121 // been acquired, or when the wait time expires (whichever is sooner). | 120 // been acquired, or when the wait time expires (whichever is sooner). |
122 static void Unregister(int sequence_number) { | 121 static void Unregister(int sequence_number) { |
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
124 | 123 |
125 RequestContextMap::iterator it = | 124 RequestContextMap::iterator it = |
126 outstanding_requests_.Get().find(sequence_number); | 125 outstanding_requests_.Get().find(sequence_number); |
127 if (it == outstanding_requests_.Get().end()) | 126 if (it == outstanding_requests_.Get().end()) |
128 return; | 127 return; |
129 | 128 |
130 RequestContext* request = it->second; | 129 RequestContext* request = it->second; |
131 DCHECK_EQ(sequence_number, request->sequence_number_); | 130 DCHECK_EQ(sequence_number, request->sequence_number_); |
132 bool received_process_group_count = request->received_process_group_count_; | 131 bool received_process_group_count = request->received_process_group_count_; |
133 int unresponsive_processes = request->processes_pending_; | 132 int unresponsive_processes = request->processes_pending_; |
134 | 133 |
135 if (request->callback_object_) | 134 if (request->callback_object_) |
136 request->callback_object_->FinishedReceivingProfilerData(); | 135 request->callback_object_->FinishedReceivingProfilerData(); |
137 | 136 |
138 delete request; | 137 delete request; |
139 outstanding_requests_.Get().erase(it); | 138 outstanding_requests_.Get().erase(it); |
140 | 139 |
141 UMA_HISTOGRAM_BOOLEAN("Profiling.ReceivedProcessGroupCount", | 140 UMA_HISTOGRAM_BOOLEAN("Profiling.ReceivedProcessGroupCount", |
142 received_process_group_count); | 141 received_process_group_count); |
143 UMA_HISTOGRAM_COUNTS("Profiling.PendingProcessNotResponding", | 142 UMA_HISTOGRAM_COUNTS("Profiling.PendingProcessNotResponding", |
144 unresponsive_processes); | 143 unresponsive_processes); |
145 } | 144 } |
146 | 145 |
147 | |
148 // Delete all the entries in |outstanding_requests_| map. | 146 // Delete all the entries in |outstanding_requests_| map. |
149 static void OnShutdown() { | 147 static void OnShutdown() { |
150 // Just in case we have any pending tasks, clear them out. | 148 // Just in case we have any pending tasks, clear them out. |
151 while (!outstanding_requests_.Get().empty()) { | 149 while (!outstanding_requests_.Get().empty()) { |
152 RequestContextMap::iterator it = outstanding_requests_.Get().begin(); | 150 RequestContextMap::iterator it = outstanding_requests_.Get().begin(); |
153 delete it->second; | 151 delete it->second; |
154 outstanding_requests_.Get().erase(it); | 152 outstanding_requests_.Get().erase(it); |
155 } | 153 } |
156 } | 154 } |
157 | 155 |
158 // Requests are made to asynchronously send data to the |callback_object_|. | 156 // Requests are made to asynchronously send data to the |callback_object_|. |
159 base::WeakPtr<TrackingSynchronizerObserver> callback_object_; | 157 base::WeakPtr<TrackingSynchronizerObserver> callback_object_; |
160 | 158 |
161 // The sequence number used by the most recent update request to contact all | 159 // The sequence number used by the most recent update request to contact all |
162 // processes. | 160 // processes. |
163 int sequence_number_; | 161 int sequence_number_; |
164 | 162 |
165 // Indicates if we have received all pending processes count. | 163 // Indicates if we have received all pending processes count. |
166 bool received_process_group_count_; | 164 bool received_process_group_count_; |
167 | 165 |
168 // The number of pending processes (browser, all renderer processes and | 166 // The number of pending processes (browser, all renderer processes and |
169 // browser child processes) that have not yet responded to requests. | 167 // browser child processes) that have not yet responded to requests. |
170 int processes_pending_; | 168 int processes_pending_; |
171 | 169 |
172 // Map of all outstanding RequestContexts, from sequence_number_ to | 170 // Map of all outstanding RequestContexts, from sequence_number_ to |
173 // RequestContext. | 171 // RequestContext. |
174 static base::LazyInstance<RequestContextMap> outstanding_requests_; | 172 static base::LazyInstance<RequestContextMap>::Leaky outstanding_requests_; |
175 }; | 173 }; |
176 | 174 |
177 // static | 175 // static |
178 base::LazyInstance<TrackingSynchronizer::RequestContext::RequestContextMap> | 176 base::LazyInstance |
179 TrackingSynchronizer::RequestContext::outstanding_requests_ = | 177 <TrackingSynchronizer::RequestContext::RequestContextMap>::Leaky |
180 LAZY_INSTANCE_INITIALIZER; | 178 TrackingSynchronizer::RequestContext::outstanding_requests_ = |
| 179 LAZY_INSTANCE_INITIALIZER; |
181 | 180 |
182 // TrackingSynchronizer methods and members. | 181 // TrackingSynchronizer methods and members. |
183 | 182 |
184 TrackingSynchronizer::TrackingSynchronizer() | 183 TrackingSynchronizer::TrackingSynchronizer() |
185 : last_used_sequence_number_(kNeverUsableSequenceNumber) { | 184 : last_used_sequence_number_(kNeverUsableSequenceNumber) { |
186 DCHECK(!g_tracking_synchronizer); | 185 DCHECK(!g_tracking_synchronizer); |
187 g_tracking_synchronizer = this; | 186 g_tracking_synchronizer = this; |
188 content::ProfilerController::GetInstance()->Register(this); | 187 content::ProfilerController::GetInstance()->Register(this); |
189 } | 188 } |
190 | 189 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 | 288 |
290 ++last_used_sequence_number_; | 289 ++last_used_sequence_number_; |
291 | 290 |
292 // Watch out for wrapping to a negative number. | 291 // Watch out for wrapping to a negative number. |
293 if (last_used_sequence_number_ < 0) | 292 if (last_used_sequence_number_ < 0) |
294 last_used_sequence_number_ = 1; | 293 last_used_sequence_number_ = 1; |
295 return last_used_sequence_number_; | 294 return last_used_sequence_number_; |
296 } | 295 } |
297 | 296 |
298 } // namespace chrome_browser_metrics | 297 } // namespace chrome_browser_metrics |
OLD | NEW |