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

Side by Side Diff: media/audio/audio_manager.cc

Issue 2934613002: Avoid shutdown crash if audio thread is hung. (Closed)
Patch Set: leaks audio manager Created 3 years, 6 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
« no previous file with comments | « media/audio/audio_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "media/audio/audio_manager.h" 5 #include "media/audio/audio_manager.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 io_task_running_ = audio_task_running_ = true; 74 io_task_running_ = audio_task_running_ = true;
75 audio_task_runner_->PostTask( 75 audio_task_runner_->PostTask(
76 FROM_HERE, 76 FROM_HERE,
77 base::Bind(&AudioManagerHelper::UpdateLastAudioThreadTimeTick, 77 base::Bind(&AudioManagerHelper::UpdateLastAudioThreadTimeTick,
78 base::Unretained(this))); 78 base::Unretained(this)));
79 monitor_task_runner_->PostTask( 79 monitor_task_runner_->PostTask(
80 FROM_HERE, base::Bind(&AudioManagerHelper::RecordAudioThreadStatus, 80 FROM_HERE, base::Bind(&AudioManagerHelper::RecordAudioThreadStatus,
81 base::Unretained(this))); 81 base::Unretained(this)));
82 } 82 }
83 83
84 bool IsAudioThreadHung() {
85 base::AutoLock lock(hang_lock_);
86 return audio_thread_status_ == THREAD_HUNG;
pfeldman 2017/06/14 22:38:30 We should not sync UI thread with potentially stal
alokp 2017/06/14 23:56:19 This function is only called during shutdown. Are
87 }
88
84 base::SingleThreadTaskRunner* monitor_task_runner() const { 89 base::SingleThreadTaskRunner* monitor_task_runner() const {
85 return monitor_task_runner_.get(); 90 return monitor_task_runner_.get();
86 } 91 }
87 AudioLogFactory* fake_log_factory() { return &fake_log_factory_; } 92 AudioLogFactory* fake_log_factory() { return &fake_log_factory_; }
88 93
89 #if defined(OS_WIN) 94 #if defined(OS_WIN)
90 // This should be called before creating an AudioManager in tests to ensure 95 // This should be called before creating an AudioManager in tests to ensure
91 // that the creating thread is COM initialized. 96 // that the creating thread is COM initialized.
92 void InitializeCOMForTesting() { 97 void InitializeCOMForTesting() {
93 com_initializer_for_testing_.reset(new base::win::ScopedCOMInitializer()); 98 com_initializer_for_testing_.reset(new base::win::ScopedCOMInitializer());
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 // Don't hold the lock while posting the next task. 202 // Don't hold the lock while posting the next task.
198 audio_task_runner_->PostDelayedTask( 203 audio_task_runner_->PostDelayedTask(
199 FROM_HERE, 204 FROM_HERE,
200 base::Bind(&AudioManagerHelper::UpdateLastAudioThreadTimeTick, 205 base::Bind(&AudioManagerHelper::UpdateLastAudioThreadTimeTick,
201 base::Unretained(this)), 206 base::Unretained(this)),
202 max_hung_task_time_ / 5); 207 max_hung_task_time_ / 5);
203 } 208 }
204 209
205 void HistogramThreadStatus(ThreadStatus status) { 210 void HistogramThreadStatus(ThreadStatus status) {
206 DCHECK(monitor_task_runner_->BelongsToCurrentThread()); 211 DCHECK(monitor_task_runner_->BelongsToCurrentThread());
212 hang_lock_.AssertAcquired();
207 audio_thread_status_ = status; 213 audio_thread_status_ = status;
208 UMA_HISTOGRAM_ENUMERATION("Media.AudioThreadStatus", audio_thread_status_, 214 UMA_HISTOGRAM_ENUMERATION("Media.AudioThreadStatus", audio_thread_status_,
209 THREAD_MAX + 1); 215 THREAD_MAX + 1);
210 } 216 }
211 217
212 FakeAudioLogFactory fake_log_factory_; 218 FakeAudioLogFactory fake_log_factory_;
213 219
214 const base::TimeDelta max_hung_task_time_ = base::TimeDelta::FromMinutes(1); 220 const base::TimeDelta max_hung_task_time_ = base::TimeDelta::FromMinutes(1);
215 scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner_; 221 scoped_refptr<base::SingleThreadTaskRunner> monitor_task_runner_;
216 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; 222 scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 const std::string& AudioManager::GetGlobalAppName() { 328 const std::string& AudioManager::GetGlobalAppName() {
323 return GetHelper()->app_name(); 329 return GetHelper()->app_name();
324 } 330 }
325 #endif 331 #endif
326 332
327 // static 333 // static
328 AudioManager* AudioManager::Get() { 334 AudioManager* AudioManager::Get() {
329 return g_last_created; 335 return g_last_created;
330 } 336 }
331 337
332 void AudioManager::Shutdown() { 338 bool AudioManager::Shutdown() {
333 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); 339 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
334 340
341 // Do not attempt to stop the audio thread if it is hung.
342 // Otherwise the current thread will hang too: crbug.com/729494
343 // TODO(olka, grunell): Will be fixed when audio is its own process.
344 if (GetHelper()->IsAudioThreadHung())
pfeldman 2017/06/14 22:38:31 Are you suggesting that upon stopping the audio th
alokp 2017/06/14 23:56:19 Yes - exactly.
345 return false;
346
335 // TODO(alokp): Suspend hang monitor. 347 // TODO(alokp): Suspend hang monitor.
336
337 if (audio_thread_->GetTaskRunner()->BelongsToCurrentThread()) { 348 if (audio_thread_->GetTaskRunner()->BelongsToCurrentThread()) {
338 ShutdownOnAudioThread(); 349 ShutdownOnAudioThread();
339 } else { 350 } else {
340 audio_thread_->GetTaskRunner()->PostTask( 351 audio_thread_->GetTaskRunner()->PostTask(
341 FROM_HERE, base::Bind(&AudioManager::ShutdownOnAudioThread, 352 FROM_HERE, base::Bind(&AudioManager::ShutdownOnAudioThread,
342 base::Unretained(this))); 353 base::Unretained(this)));
343 } 354 }
344 audio_thread_->Stop(); 355 audio_thread_->Stop();
345 shutdown_ = true; 356 shutdown_ = true;
357 return true;
346 } 358 }
347 359
348 } // namespace media 360 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698