| Index: media/audio/audio_manager_base.cc
|
| diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
|
| index 944156c66c6f8e9eb1e561ea1896b01a9c05a083..f600c27b92d0881c23cae330172b37c2d4614719 100644
|
| --- a/media/audio/audio_manager_base.cc
|
| +++ b/media/audio/audio_manager_base.cc
|
| @@ -93,6 +93,10 @@ AudioManagerBase::AudioManagerBase(
|
| AudioManagerBase::~AudioManagerBase() {
|
| DCHECK(GetTaskRunner()->BelongsToCurrentThread());
|
|
|
| + // All fake input/output streams should have been deleted.
|
| + CHECK(fake_output_streams_.empty());
|
| + CHECK(fake_input_streams_.empty());
|
| +
|
| // All the output streams should have been deleted.
|
| CHECK_EQ(0, num_output_streams_);
|
| // All the input streams should have been deleted.
|
| @@ -138,6 +142,7 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStream(
|
| break;
|
| case AudioParameters::AUDIO_FAKE:
|
| stream = FakeAudioOutputStream::MakeFakeStream(this, params);
|
| + fake_output_streams_.insert(stream);
|
| break;
|
| default:
|
| stream = NULL;
|
| @@ -183,6 +188,7 @@ AudioInputStream* AudioManagerBase::MakeAudioInputStream(
|
| break;
|
| case AudioParameters::AUDIO_FAKE:
|
| stream = FakeAudioInputStream::MakeFakeStream(this, params);
|
| + fake_input_streams_.insert(stream);
|
| break;
|
| default:
|
| stream = NULL;
|
| @@ -282,16 +288,20 @@ void AudioManagerBase::GetAudioOutputDeviceNames(
|
|
|
| void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) {
|
| DCHECK(stream);
|
| + CHECK_GT(num_output_streams_, 0);
|
| // TODO(xians) : Have a clearer destruction path for the AudioOutputStream.
|
| // For example, pass the ownership to AudioManager so it can delete the
|
| // streams.
|
| + fake_output_streams_.erase(stream);
|
| --num_output_streams_;
|
| delete stream;
|
| }
|
|
|
| void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) {
|
| DCHECK(stream);
|
| + CHECK_GT(num_input_streams_, 0);
|
| // TODO(xians) : Have a clearer destruction path for the AudioInputStream.
|
| + fake_input_streams_.erase(stream);
|
| --num_input_streams_;
|
| delete stream;
|
| }
|
| @@ -303,6 +313,28 @@ void AudioManagerBase::Shutdown() {
|
| output_dispatchers_.back()->dispatcher->Shutdown();
|
| output_dispatchers_.pop_back();
|
| }
|
| +
|
| +#if defined(OS_MACOSX)
|
| + // On mac, AudioManager runs on the main thread, loop for which stops
|
| + // processing task queue at this point. So even if tasks to close the
|
| + // streams are enqueued, they would not run leading to CHECKs getting hit
|
| + // in the destructor about open streams. Close them explicitly here.
|
| + // crbug.com/608049.
|
| + for (auto& iter = fake_output_streams_.begin();
|
| + iter != fake_output_streams_.end();) {
|
| + // Note: Closing the stream will invalidate the iterator.
|
| + // Increment the iterator before closing the stream.
|
| + AudioOutputStream* stream = *(iter++);
|
| + stream->close();
|
| + }
|
| + for (auto& iter = fake_input_streams_.begin();
|
| + iter != fake_input_streams_.end();) {
|
| + // Note: Closing the stream will invalidate the iterator.
|
| + // Increment the iterator before closing the stream.
|
| + AudioInputStream* stream = *(iter++);
|
| + stream->close();
|
| + }
|
| +#endif // OS_MACOSX
|
| }
|
|
|
| void AudioManagerBase::AddOutputDeviceChangeListener(
|
|
|