Chromium Code Reviews| 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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |