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 "content/browser/histogram_synchronizer.h" | 5 #include "content/browser/histogram_synchronizer.h" |
6 | 6 |
| 7 #include <utility> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
9 #include "base/location.h" | 11 #include "base/location.h" |
10 #include "base/logging.h" | 12 #include "base/logging.h" |
11 #include "base/metrics/histogram_delta_serialization.h" | 13 #include "base/metrics/histogram_delta_serialization.h" |
12 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
13 #include "base/pickle.h" | 15 #include "base/pickle.h" |
14 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
15 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
16 #include "base/threading/thread_restrictions.h" | 18 #include "base/threading/thread_restrictions.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 }; | 161 }; |
160 | 162 |
161 // static | 163 // static |
162 base::LazyInstance | 164 base::LazyInstance |
163 <HistogramSynchronizer::RequestContext::RequestContextMap>::Leaky | 165 <HistogramSynchronizer::RequestContext::RequestContextMap>::Leaky |
164 HistogramSynchronizer::RequestContext::outstanding_requests_ = | 166 HistogramSynchronizer::RequestContext::outstanding_requests_ = |
165 LAZY_INSTANCE_INITIALIZER; | 167 LAZY_INSTANCE_INITIALIZER; |
166 | 168 |
167 HistogramSynchronizer::HistogramSynchronizer() | 169 HistogramSynchronizer::HistogramSynchronizer() |
168 : lock_(), | 170 : lock_(), |
169 callback_thread_(NULL), | |
170 last_used_sequence_number_(kNeverUsableSequenceNumber), | 171 last_used_sequence_number_(kNeverUsableSequenceNumber), |
171 async_sequence_number_(kNeverUsableSequenceNumber) { | 172 async_sequence_number_(kNeverUsableSequenceNumber) { |
172 HistogramController::GetInstance()->Register(this); | 173 HistogramController::GetInstance()->Register(this); |
173 } | 174 } |
174 | 175 |
175 HistogramSynchronizer::~HistogramSynchronizer() { | 176 HistogramSynchronizer::~HistogramSynchronizer() { |
176 RequestContext::OnShutdown(); | 177 RequestContext::OnShutdown(); |
177 | 178 |
178 // Just in case we have any pending tasks, clear them out. | 179 // Just in case we have any pending tasks, clear them out. |
179 SetCallbackTaskAndThread(NULL, base::Closure()); | 180 SetTaskRunnerAndCallback(nullptr, base::Closure()); |
180 } | 181 } |
181 | 182 |
182 HistogramSynchronizer* HistogramSynchronizer::GetInstance() { | 183 HistogramSynchronizer* HistogramSynchronizer::GetInstance() { |
183 return base::Singleton< | 184 return base::Singleton< |
184 HistogramSynchronizer, | 185 HistogramSynchronizer, |
185 base::LeakySingletonTraits<HistogramSynchronizer>>::get(); | 186 base::LeakySingletonTraits<HistogramSynchronizer>>::get(); |
186 } | 187 } |
187 | 188 |
188 // static | 189 // static |
189 void HistogramSynchronizer::FetchHistograms() { | 190 void HistogramSynchronizer::FetchHistograms() { |
190 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 191 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
191 BrowserThread::PostTask( | 192 BrowserThread::PostTask( |
192 BrowserThread::UI, FROM_HERE, | 193 BrowserThread::UI, FROM_HERE, |
193 base::Bind(&HistogramSynchronizer::FetchHistograms)); | 194 base::Bind(&HistogramSynchronizer::FetchHistograms)); |
194 return; | 195 return; |
195 } | 196 } |
196 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 197 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
197 | 198 |
198 HistogramSynchronizer* current_synchronizer = | 199 HistogramSynchronizer* current_synchronizer = |
199 HistogramSynchronizer::GetInstance(); | 200 HistogramSynchronizer::GetInstance(); |
200 if (current_synchronizer == NULL) | 201 if (current_synchronizer == NULL) |
201 return; | 202 return; |
202 | 203 |
203 current_synchronizer->RegisterAndNotifyAllProcesses( | 204 current_synchronizer->RegisterAndNotifyAllProcesses( |
204 HistogramSynchronizer::UNKNOWN, | 205 HistogramSynchronizer::UNKNOWN, |
205 base::TimeDelta::FromMinutes(1)); | 206 base::TimeDelta::FromMinutes(1)); |
206 } | 207 } |
207 | 208 |
208 void FetchHistogramsAsynchronously(base::MessageLoop* callback_thread, | 209 void FetchHistogramsAsynchronously(scoped_refptr<base::TaskRunner> task_runner, |
209 const base::Closure& callback, | 210 const base::Closure& callback, |
210 base::TimeDelta wait_time) { | 211 base::TimeDelta wait_time) { |
211 HistogramSynchronizer::FetchHistogramsAsynchronously( | 212 HistogramSynchronizer::FetchHistogramsAsynchronously(std::move(task_runner), |
212 callback_thread, callback, wait_time); | 213 callback, wait_time); |
213 } | 214 } |
214 | 215 |
215 // static | 216 // static |
216 void HistogramSynchronizer::FetchHistogramsAsynchronously( | 217 void HistogramSynchronizer::FetchHistogramsAsynchronously( |
217 base::MessageLoop* callback_thread, | 218 scoped_refptr<base::TaskRunner> task_runner, |
218 const base::Closure& callback, | 219 const base::Closure& callback, |
219 base::TimeDelta wait_time) { | 220 base::TimeDelta wait_time) { |
220 DCHECK(callback_thread != NULL); | 221 DCHECK(task_runner); |
221 DCHECK(!callback.is_null()); | 222 DCHECK(!callback.is_null()); |
222 | 223 |
223 HistogramSynchronizer* current_synchronizer = | 224 HistogramSynchronizer* current_synchronizer = |
224 HistogramSynchronizer::GetInstance(); | 225 HistogramSynchronizer::GetInstance(); |
225 current_synchronizer->SetCallbackTaskAndThread( | 226 current_synchronizer->SetTaskRunnerAndCallback(std::move(task_runner), |
226 callback_thread, callback); | 227 callback); |
227 | 228 |
228 current_synchronizer->RegisterAndNotifyAllProcesses( | 229 current_synchronizer->RegisterAndNotifyAllProcesses( |
229 HistogramSynchronizer::ASYNC_HISTOGRAMS, wait_time); | 230 HistogramSynchronizer::ASYNC_HISTOGRAMS, wait_time); |
230 } | 231 } |
231 | 232 |
232 void HistogramSynchronizer::RegisterAndNotifyAllProcesses( | 233 void HistogramSynchronizer::RegisterAndNotifyAllProcesses( |
233 ProcessHistogramRequester requester, | 234 ProcessHistogramRequester requester, |
234 base::TimeDelta wait_time) { | 235 base::TimeDelta wait_time) { |
235 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 236 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
236 | 237 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 | 278 |
278 RequestContext* request = RequestContext::GetRequestContext(sequence_number); | 279 RequestContext* request = RequestContext::GetRequestContext(sequence_number); |
279 if (!request) | 280 if (!request) |
280 return; | 281 return; |
281 | 282 |
282 // Delete request if we have heard back from all child processes. | 283 // Delete request if we have heard back from all child processes. |
283 request->DecrementProcessesPending(); | 284 request->DecrementProcessesPending(); |
284 request->DeleteIfAllDone(); | 285 request->DeleteIfAllDone(); |
285 } | 286 } |
286 | 287 |
287 void HistogramSynchronizer::SetCallbackTaskAndThread( | 288 void HistogramSynchronizer::SetTaskRunnerAndCallback( |
288 base::MessageLoop* callback_thread, | 289 scoped_refptr<base::TaskRunner> task_runner, |
289 const base::Closure& callback) { | 290 const base::Closure& callback) { |
290 base::Closure old_callback; | 291 base::Closure old_callback; |
291 base::MessageLoop* old_thread = NULL; | 292 scoped_refptr<base::TaskRunner> old_task_runner; |
292 { | 293 { |
293 base::AutoLock auto_lock(lock_); | 294 base::AutoLock auto_lock(lock_); |
294 old_callback = callback_; | 295 old_callback = callback_; |
295 callback_ = callback; | 296 callback_ = callback; |
296 old_thread = callback_thread_; | 297 old_task_runner = std::move(callback_task_runner_); |
297 callback_thread_ = callback_thread; | 298 callback_task_runner_ = std::move(task_runner); |
298 // Prevent premature calling of our new callbacks. | 299 // Prevent premature calling of our new callbacks. |
299 async_sequence_number_ = kNeverUsableSequenceNumber; | 300 async_sequence_number_ = kNeverUsableSequenceNumber; |
300 } | 301 } |
301 // Just in case there was a task pending.... | 302 // Just in case there was a task pending.... |
302 InternalPostTask(old_thread, old_callback); | 303 InternalPostTask(std::move(old_task_runner), old_callback); |
303 } | 304 } |
304 | 305 |
305 void HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback( | 306 void HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback( |
306 int sequence_number) { | 307 int sequence_number) { |
307 base::Closure callback; | 308 base::Closure callback; |
308 base::MessageLoop* thread = NULL; | 309 scoped_refptr<base::TaskRunner> task_runner; |
309 { | 310 { |
310 base::AutoLock lock(lock_); | 311 base::AutoLock lock(lock_); |
311 if (sequence_number != async_sequence_number_) | 312 if (sequence_number != async_sequence_number_) |
312 return; | 313 return; |
313 callback = callback_; | 314 callback = callback_; |
314 thread = callback_thread_; | 315 task_runner = std::move(callback_task_runner_); |
315 callback_.Reset(); | 316 callback_.Reset(); |
316 callback_thread_ = NULL; | |
317 } | 317 } |
318 InternalPostTask(thread, callback); | 318 InternalPostTask(std::move(task_runner), callback); |
319 } | 319 } |
320 | 320 |
321 void HistogramSynchronizer::InternalPostTask(base::MessageLoop* thread, | 321 void HistogramSynchronizer::InternalPostTask( |
322 const base::Closure& callback) { | 322 scoped_refptr<base::TaskRunner> task_runner, |
323 if (callback.is_null() || !thread) | 323 const base::Closure& callback) { |
| 324 if (callback.is_null() || !task_runner) |
324 return; | 325 return; |
325 thread->task_runner()->PostTask(FROM_HERE, callback); | 326 task_runner->PostTask(FROM_HERE, callback); |
326 } | 327 } |
327 | 328 |
328 int HistogramSynchronizer::GetNextAvailableSequenceNumber( | 329 int HistogramSynchronizer::GetNextAvailableSequenceNumber( |
329 ProcessHistogramRequester requester) { | 330 ProcessHistogramRequester requester) { |
330 base::AutoLock auto_lock(lock_); | 331 base::AutoLock auto_lock(lock_); |
331 ++last_used_sequence_number_; | 332 ++last_used_sequence_number_; |
332 // Watch out for wrapping to a negative number. | 333 // Watch out for wrapping to a negative number. |
333 if (last_used_sequence_number_ < 0) { | 334 if (last_used_sequence_number_ < 0) { |
334 // Bypass the reserved number, which is used when a renderer spontaneously | 335 // Bypass the reserved number, which is used when a renderer spontaneously |
335 // decides to send some histogram data. | 336 // decides to send some histogram data. |
336 last_used_sequence_number_ = | 337 last_used_sequence_number_ = |
337 kHistogramSynchronizerReservedSequenceNumber + 1; | 338 kHistogramSynchronizerReservedSequenceNumber + 1; |
338 } | 339 } |
339 DCHECK_NE(last_used_sequence_number_, | 340 DCHECK_NE(last_used_sequence_number_, |
340 kHistogramSynchronizerReservedSequenceNumber); | 341 kHistogramSynchronizerReservedSequenceNumber); |
341 if (requester == ASYNC_HISTOGRAMS) | 342 if (requester == ASYNC_HISTOGRAMS) |
342 async_sequence_number_ = last_used_sequence_number_; | 343 async_sequence_number_ = last_used_sequence_number_; |
343 return last_used_sequence_number_; | 344 return last_used_sequence_number_; |
344 } | 345 } |
345 | 346 |
346 } // namespace content | 347 } // namespace content |
OLD | NEW |