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 |