| 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 |