Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: chrome/browser/metrics/thread_watcher.cc

Issue 2295983002: Fix memory leak in ThreadWatcher. (Closed)
Patch Set: Address feedback from isherman in comment #17 Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/thread_watcher.h" 5 #include "chrome/browser/metrics/thread_watcher.h"
6 6
7 #include <math.h> // ceil 7 #include <math.h> // ceil
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 if (!WatchDogThread::CurrentlyOnWatchDogThread()) { 72 if (!WatchDogThread::CurrentlyOnWatchDogThread()) {
73 WatchDogThread::PostTask( 73 WatchDogThread::PostTask(
74 FROM_HERE, 74 FROM_HERE,
75 base::Bind(&ThreadWatcher::StartWatching, params)); 75 base::Bind(&ThreadWatcher::StartWatching, params));
76 return; 76 return;
77 } 77 }
78 78
79 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); 79 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread());
80 80
81 // Create a new thread watcher object for the given thread and activate it. 81 // Create a new thread watcher object for the given thread and activate it.
82 ThreadWatcher* watcher = new ThreadWatcher(params); 82 std::unique_ptr<ThreadWatcher> watcher(new ThreadWatcher(params));
83 83
84 DCHECK(watcher);
85 // If we couldn't register the thread watcher object, we are shutting down, 84 // If we couldn't register the thread watcher object, we are shutting down,
86 // then don't activate thread watching. 85 // so don't activate thread watching.
87 if (!ThreadWatcherList::IsRegistered(params.thread_id)) 86 if (!ThreadWatcherList::Register(std::move(watcher)))
88 return; 87 return;
89 watcher->ActivateThreadWatching(); 88 watcher->ActivateThreadWatching();
Jakob Kummerow 2016/09/01 13:35:17 I believe using |watcher| after calling std::move(
Ilya Sherman 2016/09/01 18:15:18 Ah, good call -- my bad for missing that! One pos
90 } 89 }
91 90
92 void ThreadWatcher::ActivateThreadWatching() { 91 void ThreadWatcher::ActivateThreadWatching() {
93 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); 92 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread());
94 if (active_) return; 93 if (active_) return;
95 active_ = true; 94 active_ = true;
96 ping_count_ = unresponsive_threshold_; 95 ping_count_ = unresponsive_threshold_;
97 ResetHangCounters(); 96 ResetHangCounters();
98 base::ThreadTaskRunnerHandle::Get()->PostTask( 97 base::ThreadTaskRunnerHandle::Get()->PostTask(
99 FROM_HERE, base::Bind(&ThreadWatcher::PostPingMessage, 98 FROM_HERE, base::Bind(&ThreadWatcher::PostPingMessage,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 216 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
218 FROM_HERE, 217 FROM_HERE,
219 base::Bind(&ThreadWatcher::OnCheckResponsiveness, 218 base::Bind(&ThreadWatcher::OnCheckResponsiveness,
220 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), 219 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_),
221 unresponsive_time_); 220 unresponsive_time_);
222 responsive_ = false; 221 responsive_ = false;
223 } 222 }
224 223
225 void ThreadWatcher::Initialize() { 224 void ThreadWatcher::Initialize() {
226 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); 225 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread());
227 ThreadWatcherList::Register(this);
228 226
229 const std::string response_time_histogram_name = 227 const std::string response_time_histogram_name =
230 "ThreadWatcher.ResponseTime." + thread_name_; 228 "ThreadWatcher.ResponseTime." + thread_name_;
231 response_time_histogram_ = base::Histogram::FactoryTimeGet( 229 response_time_histogram_ = base::Histogram::FactoryTimeGet(
232 response_time_histogram_name, 230 response_time_histogram_name,
233 base::TimeDelta::FromMilliseconds(1), 231 base::TimeDelta::FromMilliseconds(1),
234 base::TimeDelta::FromSeconds(100), 50, 232 base::TimeDelta::FromSeconds(100), 50,
235 base::Histogram::kUmaTargetedHistogramFlag); 233 base::Histogram::kUmaTargetedHistogramFlag);
236 234
237 const std::string unresponsive_time_histogram_name = 235 const std::string unresponsive_time_histogram_name =
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 } 373 }
376 374
377 // static 375 // static
378 void ThreadWatcherList::StopWatchingAll() { 376 void ThreadWatcherList::StopWatchingAll() {
379 // TODO(rtenneti): Enable ThreadWatcher. 377 // TODO(rtenneti): Enable ThreadWatcher.
380 ThreadWatcherObserver::RemoveNotifications(); 378 ThreadWatcherObserver::RemoveNotifications();
381 DeleteAll(); 379 DeleteAll();
382 } 380 }
383 381
384 // static 382 // static
385 void ThreadWatcherList::Register(ThreadWatcher* watcher) { 383 bool ThreadWatcherList::Register(std::unique_ptr<ThreadWatcher> watcher) {
386 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); 384 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread());
387 if (!g_thread_watcher_list_) 385 if (!g_thread_watcher_list_)
388 return; 386 return false;
389 DCHECK(!g_thread_watcher_list_->Find(watcher->thread_id())); 387 content::BrowserThread::ID thread_id = watcher->thread_id();
390 g_thread_watcher_list_->registered_[watcher->thread_id()] = watcher; 388 DCHECK(g_thread_watcher_list_->registered_.count(thread_id) == 0);
389 g_thread_watcher_list_->registered_[thread_id] = watcher.release();
390 return true;
391 } 391 }
392 392
393 // static 393 // static
394 bool ThreadWatcherList::IsRegistered(const BrowserThread::ID thread_id) {
395 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread());
396 return nullptr != ThreadWatcherList::Find(thread_id);
397 }
398
399 // static
400 void ThreadWatcherList::GetStatusOfThreads( 394 void ThreadWatcherList::GetStatusOfThreads(
401 uint32_t* responding_thread_count, 395 uint32_t* responding_thread_count,
402 uint32_t* unresponding_thread_count) { 396 uint32_t* unresponding_thread_count) {
403 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); 397 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread());
404 *responding_thread_count = 0; 398 *responding_thread_count = 0;
405 *unresponding_thread_count = 0; 399 *unresponding_thread_count = 0;
406 if (!g_thread_watcher_list_) 400 if (!g_thread_watcher_list_)
407 return; 401 return;
408 402
409 for (RegistrationList::iterator it = 403 for (RegistrationList::iterator it =
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 993
1000 #if defined(OS_WIN) 994 #if defined(OS_WIN)
1001 // On Windows XP, give twice the time for shutdown. 995 // On Windows XP, give twice the time for shutdown.
1002 if (base::win::GetVersion() <= base::win::VERSION_XP) 996 if (base::win::GetVersion() <= base::win::VERSION_XP)
1003 actual_duration *= 2; 997 actual_duration *= 2;
1004 #endif 998 #endif
1005 999
1006 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); 1000 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration);
1007 shutdown_watchdog_->Arm(); 1001 shutdown_watchdog_->Arm();
1008 } 1002 }
OLDNEW
« no previous file with comments | « chrome/browser/metrics/thread_watcher.h ('k') | chrome/browser/metrics/thread_watcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698