Commit d4b8bc0f authored by Oskar Sundbom's avatar Oskar Sundbom Committed by Commit Bot

Windows: Retain initial IMMDeviceEnumerator throughout

Speculative fix for what looks like a race during CoreAudio
initialization. The device enumerator created to ensure for CoreAudio
availability is leaked rather than destroyed immediately after
construction.

Bug: 955434
Change-Id: Ifa70350691448ec6ba57c9eb2b93106aa8edf65b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1584276Reviewed-by: default avatarOlga Sharonova <olka@chromium.org>
Commit-Queue: Oskar Sundbom <ossu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#654447}
parent ce48c3c4
...@@ -149,9 +149,9 @@ AudioManagerWin::AudioManagerWin(std::unique_ptr<AudioThread> audio_thread, ...@@ -149,9 +149,9 @@ AudioManagerWin::AudioManagerWin(std::unique_ptr<AudioThread> audio_thread,
AudioLogFactory* audio_log_factory) AudioLogFactory* audio_log_factory)
: AudioManagerBase(std::move(audio_thread), audio_log_factory) { : AudioManagerBase(std::move(audio_thread), audio_log_factory) {
// |CoreAudioUtil::IsSupported()| uses static variables to avoid doing // |CoreAudioUtil::IsSupported()| uses static variables to avoid doing
// multiple initializations. This is however not thread safe. // multiple initializations. This is thread safe but call it here explicitly
// So, here we call it explicitly before we kick off the audio thread // to ensure initialization is done on the main thread and before we do any
// or do any other work. // other work.
CoreAudioUtil::IsSupported(); CoreAudioUtil::IsSupported();
SetMaxOutputStreamsAllowed(kMaxOutputStreams); SetMaxOutputStreamsAllowed(kMaxOutputStreams);
......
...@@ -413,13 +413,13 @@ ChannelLayout GetChannelLayout( ...@@ -413,13 +413,13 @@ ChannelLayout GetChannelLayout(
return channel_layout; return channel_layout;
} }
bool IsSupportedInternal() { IMMDeviceEnumerator* IsSupportedInternal() {
// It is possible to force usage of WaveXxx APIs by using a command line // It is possible to force usage of WaveXxx APIs by using a command line
// flag. // flag.
const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
if (cmd_line->HasSwitch(switches::kForceWaveAudio)) { if (cmd_line->HasSwitch(switches::kForceWaveAudio)) {
DVLOG(1) << "Forcing usage of Windows WaveXxx APIs"; DVLOG(1) << "Forcing usage of Windows WaveXxx APIs";
return false; return nullptr;
} }
// Verify that it is possible to a create the IMMDeviceEnumerator interface. // Verify that it is possible to a create the IMMDeviceEnumerator interface.
...@@ -430,10 +430,10 @@ bool IsSupportedInternal() { ...@@ -430,10 +430,10 @@ bool IsSupportedInternal() {
LOG(ERROR) LOG(ERROR)
<< "Failed to create Core Audio device enumerator on thread with ID " << "Failed to create Core Audio device enumerator on thread with ID "
<< GetCurrentThreadId(); << GetCurrentThreadId();
return false; return nullptr;
} }
return true; return device_enumerator.Detach();
} }
// Retrieve an audio device specified by |device_id| or a default device // Retrieve an audio device specified by |device_id| or a default device
...@@ -647,8 +647,10 @@ size_t CoreAudioUtil::WaveFormatWrapper::size() const { ...@@ -647,8 +647,10 @@ size_t CoreAudioUtil::WaveFormatWrapper::size() const {
} }
bool CoreAudioUtil::IsSupported() { bool CoreAudioUtil::IsSupported() {
static bool g_is_supported = IsSupportedInternal(); // Hold on to the device enumerator throughout, to avoid multiple
return g_is_supported; // de-/initializations of CoreAudio. See: crbug.com/955434
static IMMDeviceEnumerator* g_enumerator = IsSupportedInternal();
return g_enumerator != nullptr;
} }
// CoreAudioUtil implementation. // CoreAudioUtil implementation.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment