Index: media/audio/audio_manager_base.cc |
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc |
index 0b192523d4b3f65e624246b3c7b712053288a7da..f2ae2540f732b789d0e55abce906525ef78e6b8a 100644 |
--- a/media/audio/audio_manager_base.cc |
+++ b/media/audio/audio_manager_base.cc |
@@ -81,7 +81,8 @@ AudioManagerBase::AudioManagerBase(AudioLogFactory* audio_log_factory) |
output_listeners_( |
ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), |
audio_thread_("AudioThread"), |
- audio_log_factory_(audio_log_factory) { |
+ audio_log_factory_(audio_log_factory), |
+ in_shutdown_(0) { |
#if defined(OS_WIN) |
audio_thread_.init_com_with_mta(true); |
#elif defined(OS_MACOSX) |
@@ -138,6 +139,8 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
// TODO(miu): Fix ~50 call points across several unit test modules to call |
// this method on the audio thread, then uncomment the following: |
// DCHECK(task_runner_->BelongsToCurrentThread()); |
+ if (base::AtomicRefCountIsOne(&in_shutdown_)) |
+ return NULL; |
if (!params.IsValid()) { |
DLOG(ERROR) << "Audio parameters are invalid"; |
@@ -187,6 +190,8 @@ AudioInputStream* AudioManagerBase::MakeAudioInputStream( |
// TODO(miu): Fix ~20 call points across several unit test modules to call |
// this method on the audio thread, then uncomment the following: |
// DCHECK(task_runner_->BelongsToCurrentThread()); |
+ if (base::AtomicRefCountIsOne(&in_shutdown_)) |
+ return NULL; |
if (!params.IsValid() || (params.channels() > kMaxInputChannels) || |
device_id.empty()) { |
@@ -228,6 +233,8 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStreamProxy( |
const AudioParameters& params, |
const std::string& device_id) { |
DCHECK(task_runner_->BelongsToCurrentThread()); |
+ if (base::AtomicRefCountIsOne(&in_shutdown_)) |
+ return NULL; |
// If the caller supplied an empty device id to select the default device, |
// we fetch the actual device id of the default device so that the lookup |
@@ -322,6 +329,9 @@ void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
} |
void AudioManagerBase::Shutdown() { |
+ DCHECK(base::AtomicRefCountIsZero(&in_shutdown_)); |
+ base::AtomicRefCountInc(&in_shutdown_); |
+ |
// Only true when we're sharing the UI message loop with the browser. The UI |
// loop is no longer running at this time and browser destruction is imminent. |
if (task_runner_->BelongsToCurrentThread()) { |
@@ -337,6 +347,7 @@ void AudioManagerBase::Shutdown() { |
void AudioManagerBase::ShutdownOnAudioThread() { |
DCHECK(task_runner_->BelongsToCurrentThread()); |
+ DCHECK(base::AtomicRefCountIsOne(&in_shutdown_)); |
AudioOutputDispatchers::iterator it = output_dispatchers_.begin(); |
for (; it != output_dispatchers_.end(); ++it) { |
@@ -369,6 +380,8 @@ void AudioManagerBase::RemoveOutputDeviceChangeListener( |
void AudioManagerBase::NotifyAllOutputDeviceChangeListeners() { |
DCHECK(task_runner_->BelongsToCurrentThread()); |
+ if (base::AtomicRefCountIsOne(&in_shutdown_)) |
+ return; |
DVLOG(1) << "Firing OnDeviceChange() notifications."; |
FOR_EACH_OBSERVER(AudioDeviceListener, output_listeners_, OnDeviceChange()); |
} |