diff options
author | dalecurtis <dalecurtis@chromium.org> | 2015-11-10 10:25:58 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-10 18:26:52 +0000 |
commit | dd1b4ad61b745e8d75195cd0b4938086d3b6062d (patch) | |
tree | 2c9c7b807f5e10ced053650cdd95bb66a08b60b9 | |
parent | 2641bbb33465cf9d2442886162e4911cd91c011c (diff) | |
download | chromium_src-dd1b4ad61b745e8d75195cd0b4938086d3b6062d.zip chromium_src-dd1b4ad61b745e8d75195cd0b4938086d3b6062d.tar.gz chromium_src-dd1b4ad61b745e8d75195cd0b4938086d3b6062d.tar.bz2 |
Revert of Stall audio thread after device changes to avoid 3rd party deadlock. (patchset #2 id:20001 of https://codereview.chromium.org/1428413003/ )
Reason for revert:
Did not reduce the number of crash reports, so reverting. :(
Original issue's description:
> Stall audio thread after device changes to avoid 3rd party deadlock.
>
> Speculative change to see if stalling callbacks into the Windows
> audio subsystem after a device change is detected will reduce the
> frequency of deadlock in 3rd party WDM drivers.
>
> This change reroutes both input and output device changes through
> the AudioManagerWin, where a simple sleep on the audio thread
> stalls any outstanding activity.
>
> The stall should be fine as the audio thread is used primarily as
> an asychronous control channel. I've chosen a stall over a post
> delayed task to ensure that any outstanding tasks are prevented.
>
> If this CL is successful we can experiment with loosening to a
> PostDelayedTask will still bear fruit.
>
> BUG=422522
> TEST=device change works as normal.
>
> Committed: https://crrev.com/6ffe80ed4dea8b85925ba6dfa2a0cb8f472fb951
> Cr-Commit-Position: refs/heads/master@{#358707}
TBR=watk@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=422522
Review URL: https://codereview.chromium.org/1430423002
Cr-Commit-Position: refs/heads/master@{#358854}
-rw-r--r-- | media/audio/win/audio_device_listener_win.cc | 10 | ||||
-rw-r--r-- | media/audio/win/audio_device_listener_win.h | 8 | ||||
-rw-r--r-- | media/audio/win/audio_device_listener_win_unittest.cc | 24 | ||||
-rw-r--r-- | media/audio/win/audio_manager_win.cc | 21 | ||||
-rw-r--r-- | media/audio/win/audio_manager_win.h | 9 |
5 files changed, 20 insertions, 52 deletions
diff --git a/media/audio/win/audio_device_listener_win.cc b/media/audio/win/audio_device_listener_win.cc index 056ab7c..505007b 100644 --- a/media/audio/win/audio_device_listener_win.cc +++ b/media/audio/win/audio_device_listener_win.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "base/system_monitor/system_monitor.h" #include "base/time/default_tick_clock.h" #include "base/win/scoped_co_mem.h" #include "base/win/windows_version.h" @@ -30,7 +31,7 @@ static std::string RoleToString(ERole role) { } } -AudioDeviceListenerWin::AudioDeviceListenerWin(const ListenerCB& listener_cb) +AudioDeviceListenerWin::AudioDeviceListenerWin(const base::Closure& listener_cb) : listener_cb_(listener_cb), tick_clock_(new base::DefaultTickClock()) { CHECK(CoreAudioUtil::IsSupported()); @@ -97,7 +98,10 @@ STDMETHODIMP AudioDeviceListenerWin::OnDeviceRemoved(LPCWSTR device_id) { STDMETHODIMP AudioDeviceListenerWin::OnDeviceStateChanged(LPCWSTR device_id, DWORD new_state) { - listener_cb_.Run(kInputDeviceChange); + base::SystemMonitor* monitor = base::SystemMonitor::Get(); + if (monitor) + monitor->ProcessDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); + return S_OK; } @@ -127,7 +131,7 @@ STDMETHODIMP AudioDeviceListenerWin::OnDefaultDeviceChanged( now - last_device_change_time_ > base::TimeDelta::FromMilliseconds(kDeviceChangeLimitMs)) { last_device_change_time_ = now; - listener_cb_.Run(kOutputDeviceChange); + listener_cb_.Run(); did_run_listener_cb = true; } diff --git a/media/audio/win/audio_device_listener_win.h b/media/audio/win/audio_device_listener_win.h index 8875269..053afa6 100644 --- a/media/audio/win/audio_device_listener_win.h +++ b/media/audio/win/audio_device_listener_win.h @@ -31,14 +31,10 @@ namespace media { // TODO(dalecurtis, henrika): Support input device changes. class MEDIA_EXPORT AudioDeviceListenerWin : public IMMNotificationClient { public: - // Callback returns whether input or output devices have changed. - enum DeviceNotificationType { kInputDeviceChange, kOutputDeviceChange }; - using ListenerCB = base::Callback<void(DeviceNotificationType)>; - // The listener callback will be called from a system level multimedia thread, // thus the callee must be thread safe. |listener| is a permanent callback // and must outlive AudioDeviceListenerWin. - explicit AudioDeviceListenerWin(const ListenerCB& listener_cb); + explicit AudioDeviceListenerWin(const base::Closure& listener_cb); virtual ~AudioDeviceListenerWin(); private: @@ -60,7 +56,7 @@ class MEDIA_EXPORT AudioDeviceListenerWin : public IMMNotificationClient { ERole role, LPCWSTR new_default_device_id) override; - ListenerCB listener_cb_; + base::Closure listener_cb_; ScopedComPtr<IMMDeviceEnumerator> device_enumerator_; // Used to rate limit device change events. diff --git a/media/audio/win/audio_device_listener_win_unittest.cc b/media/audio/win/audio_device_listener_win_unittest.cc index 855c590..4b78d93 100644 --- a/media/audio/win/audio_device_listener_win_unittest.cc +++ b/media/audio/win/audio_device_listener_win_unittest.cc @@ -60,8 +60,8 @@ class AudioDeviceListenerWinTest : public testing::Test { base::ASCIIToUTF16(new_device_id).c_str()) == S_OK; } - MOCK_METHOD1(OnDeviceChange, - void(AudioDeviceListenerWin::DeviceNotificationType)); + + MOCK_METHOD0(OnDeviceChange, void()); private: ScopedCOMInitializer com_init_; @@ -75,16 +75,12 @@ class AudioDeviceListenerWinTest : public testing::Test { TEST_F(AudioDeviceListenerWinTest, OutputDeviceChange) { ABORT_AUDIO_TEST_IF_NOT(CoreAudioUtil::IsSupported()); - EXPECT_CALL(*this, - OnDeviceChange(AudioDeviceListenerWin::kOutputDeviceChange)) - .Times(1); + EXPECT_CALL(*this, OnDeviceChange()).Times(1); ASSERT_TRUE(SimulateDefaultOutputDeviceChange(kFirstTestDevice)); testing::Mock::VerifyAndClear(this); AdvanceLastDeviceChangeTime(); - EXPECT_CALL(*this, - OnDeviceChange(AudioDeviceListenerWin::kOutputDeviceChange)) - .Times(1); + EXPECT_CALL(*this, OnDeviceChange()).Times(1); ASSERT_TRUE(SimulateDefaultOutputDeviceChange(kSecondTestDevice)); // The second device event should be ignored since it occurs too soon. @@ -96,23 +92,17 @@ TEST_F(AudioDeviceListenerWinTest, OutputDeviceChange) { TEST_F(AudioDeviceListenerWinTest, NullOutputDeviceChange) { ABORT_AUDIO_TEST_IF_NOT(CoreAudioUtil::IsSupported()); - EXPECT_CALL(*this, - OnDeviceChange(AudioDeviceListenerWin::kOutputDeviceChange)) - .Times(1); + EXPECT_CALL(*this, OnDeviceChange()).Times(1); ASSERT_TRUE(SimulateNullDefaultOutputDeviceChange()); testing::Mock::VerifyAndClear(this); AdvanceLastDeviceChangeTime(); - EXPECT_CALL(*this, - OnDeviceChange(AudioDeviceListenerWin::kOutputDeviceChange)) - .Times(1); + EXPECT_CALL(*this, OnDeviceChange()).Times(1); ASSERT_TRUE(SimulateDefaultOutputDeviceChange(kFirstTestDevice)); testing::Mock::VerifyAndClear(this); AdvanceLastDeviceChangeTime(); - EXPECT_CALL(*this, - OnDeviceChange(AudioDeviceListenerWin::kOutputDeviceChange)) - .Times(1); + EXPECT_CALL(*this, OnDeviceChange()).Times(1); ASSERT_TRUE(SimulateNullDefaultOutputDeviceChange()); } diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc index 0b97afb..70e6c1b 100644 --- a/media/audio/win/audio_manager_win.cc +++ b/media/audio/win/audio_manager_win.cc @@ -21,9 +21,9 @@ #include "base/process/launch.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "base/system_monitor/system_monitor.h" #include "base/win/windows_version.h" #include "media/audio/audio_parameters.h" +#include "media/audio/win/audio_device_listener_win.h" #include "media/audio/win/audio_low_latency_input_win.h" #include "media/audio/win/audio_low_latency_output_win.h" #include "media/audio/win/audio_manager_win.h" @@ -171,7 +171,7 @@ void AudioManagerWin::InitializeOnAudioThread() { // AudioDeviceListenerWin must be initialized on a COM thread and should // only be used if WASAPI / Core Audio is supported. output_device_listener_.reset(new AudioDeviceListenerWin(BindToCurrentLoop( - base::Bind(&AudioManagerWin::StallAudioThreadAfterDeviceChange, + base::Bind(&AudioManagerWin::NotifyAllOutputDeviceChangeListeners, base::Unretained(this))))); } } @@ -538,23 +538,6 @@ AudioInputStream* AudioManagerWin::CreatePCMWaveInAudioInputStream( xp_device_id); } -void AudioManagerWin::StallAudioThreadAfterDeviceChange( - AudioDeviceListenerWin::DeviceNotificationType notification_type) { - base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1)); - - if (notification_type == AudioDeviceListenerWin::kInputDeviceChange) { - base::SystemMonitor* monitor = base::SystemMonitor::Get(); - if (monitor) { - monitor->ProcessDevicesChanged( - base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); - } - return; - } - - DCHECK_EQ(notification_type, AudioDeviceListenerWin::kOutputDeviceChange); - NotifyAllOutputDeviceChangeListeners(); -} - /// static AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) { return new AudioManagerWin(audio_log_factory); diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h index 3d33b55..9826566 100644 --- a/media/audio/win/audio_manager_win.h +++ b/media/audio/win/audio_manager_win.h @@ -8,10 +8,11 @@ #include <string> #include "media/audio/audio_manager_base.h" -#include "media/audio/win/audio_device_listener_win.h" namespace media { +class AudioDeviceListenerWin; + // Windows implementation of the AudioManager singleton. This class is internal // to the audio output and only internal users can call methods not exposed by // the AudioManager class. @@ -87,12 +88,6 @@ class MEDIA_EXPORT AudioManagerWin : public AudioManagerBase { void GetAudioDeviceNamesImpl(bool input, AudioDeviceNames* device_names); - // We frequently see deadlock in third party Windows audio drivers, so after - // a device change is detected, stall for a second before allowing calls into - // the Windows audio subsystem. See http://crbug.com/422522 - void StallAudioThreadAfterDeviceChange( - AudioDeviceListenerWin::DeviceNotificationType notification_type); - // Listen for output device changes. scoped_ptr<AudioDeviceListenerWin> output_device_listener_; |