OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "tools/cygprofile/cygprofile.h" | 5 #include "tools/cygprofile/cygprofile.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <pthread.h> | 8 #include <pthread.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <stdint.h> | 10 #include <stdint.h> |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 | 289 |
290 ThreadLogsManager::~ThreadLogsManager() { | 290 ThreadLogsManager::~ThreadLogsManager() { |
291 // Note that the internal thread does some work until it sees |flush_thread_| | 291 // Note that the internal thread does some work until it sees |flush_thread_| |
292 // = NULL. | 292 // = NULL. |
293 std::unique_ptr<Thread> flush_thread; | 293 std::unique_ptr<Thread> flush_thread; |
294 { | 294 { |
295 base::AutoLock auto_lock(lock_); | 295 base::AutoLock auto_lock(lock_); |
296 flush_thread_.swap(flush_thread); | 296 flush_thread_.swap(flush_thread); |
297 } | 297 } |
298 flush_thread.reset(); // Joins the flush thread. | 298 flush_thread.reset(); // Joins the flush thread. |
299 | |
300 base::STLDeleteContainerPointers(logs_.begin(), logs_.end()); | |
301 } | 299 } |
302 | 300 |
303 void ThreadLogsManager::AddLog(std::unique_ptr<ThreadLog> new_log) { | 301 void ThreadLogsManager::AddLog(std::unique_ptr<ThreadLog> new_log) { |
304 base::AutoLock auto_lock(lock_); | 302 base::AutoLock auto_lock(lock_); |
305 | 303 |
306 if (logs_.empty()) | 304 if (logs_.empty()) |
307 StartInternalFlushThread_Locked(); | 305 StartInternalFlushThread_Locked(); |
308 | 306 |
309 logs_.push_back(new_log.release()); | 307 logs_.push_back(std::move(new_log)); |
310 } | 308 } |
311 | 309 |
312 void ThreadLogsManager::StartInternalFlushThread_Locked() { | 310 void ThreadLogsManager::StartInternalFlushThread_Locked() { |
313 lock_.AssertAcquired(); | 311 lock_.AssertAcquired(); |
314 CHECK(!flush_thread_); | 312 CHECK(!flush_thread_); |
315 // Note that the |flush_thread_| joins at destruction which guarantees that it | 313 // Note that the |flush_thread_| joins at destruction which guarantees that it |
316 // will never outlive |this|, i.e. it's safe not to use ref-counting. | 314 // will never outlive |this|, i.e. it's safe not to use ref-counting. |
317 flush_thread_.reset( | 315 flush_thread_.reset( |
318 new Thread(base::Bind(&ThreadLogsManager::FlushAllLogsOnFlushThread, | 316 new Thread(base::Bind(&ThreadLogsManager::FlushAllLogsOnFlushThread, |
319 base::Unretained(this)))); | 317 base::Unretained(this)))); |
(...skipping 18 matching lines...) Expand all Loading... |
338 // Sleep for a few secs and then flush all thread's buffers. There is a | 336 // Sleep for a few secs and then flush all thread's buffers. There is a |
339 // danger that, when quitting Chrome, this thread may see unallocated data | 337 // danger that, when quitting Chrome, this thread may see unallocated data |
340 // and segfault. We do not care because we need logs when Chrome is working. | 338 // and segfault. We do not care because we need logs when Chrome is working. |
341 wait_callback_.Run(); | 339 wait_callback_.Run(); |
342 | 340 |
343 // Copy the ThreadLog pointers to avoid acquiring both the logs manager's | 341 // Copy the ThreadLog pointers to avoid acquiring both the logs manager's |
344 // lock and the one for individual thread logs. | 342 // lock and the one for individual thread logs. |
345 std::vector<ThreadLog*> thread_logs_copy; | 343 std::vector<ThreadLog*> thread_logs_copy; |
346 { | 344 { |
347 base::AutoLock auto_lock(lock_); | 345 base::AutoLock auto_lock(lock_); |
348 thread_logs_copy = logs_; | 346 for (const auto& log : logs_) |
| 347 thread_logs_copy.push_back(log.get()); |
349 } | 348 } |
350 | 349 |
351 // Move the logs' data before flushing them so that the mutexes are not | 350 // Move the logs' data before flushing them so that the mutexes are not |
352 // acquired for too long. | 351 // acquired for too long. |
353 std::vector<LogData> logs; | 352 std::vector<LogData> logs; |
354 for (std::vector<ThreadLog*>::const_iterator it = | 353 for (std::vector<ThreadLog*>::const_iterator it = |
355 thread_logs_copy.begin(); | 354 thread_logs_copy.begin(); |
356 it != thread_logs_copy.end(); ++it) { | 355 it != thread_logs_copy.end(); ++it) { |
357 ThreadLog* const thread_log = *it; | 356 ThreadLog* const thread_log = *it; |
358 LogData log_data(thread_log); | 357 LogData log_data(thread_log); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 } | 397 } |
399 | 398 |
400 if (thread_log != kMagicBeingConstructed) | 399 if (thread_log != kMagicBeingConstructed) |
401 thread_log->AddEntry(this_fn); | 400 thread_log->AddEntry(this_fn); |
402 } | 401 } |
403 | 402 |
404 void __cyg_profile_func_exit(void* this_fn, void* call_site) {} | 403 void __cyg_profile_func_exit(void* this_fn, void* call_site) {} |
405 | 404 |
406 } // extern "C" | 405 } // extern "C" |
407 } // namespace cygprofile | 406 } // namespace cygprofile |
OLD | NEW |