From c5a372ab2a74ff5b81c6611bbfefe3d8ddad11fd Mon Sep 17 00:00:00 2001 From: Silent Date: Fri, 16 Aug 2019 23:53:47 +0200 Subject: AudioCommon/WASAPI: Use WRL/WIL whenever possible This fixes numerous resource leaks, as not every return path cleaned every created resource Now they are all managed automatically and "commited" to WASAPIStream class fields only after it's certain they initialized properly --- Source/Core/AudioCommon/WASAPIStream.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'Source/Core/AudioCommon/WASAPIStream.h') diff --git a/Source/Core/AudioCommon/WASAPIStream.h b/Source/Core/AudioCommon/WASAPIStream.h index 54becb68c0..39d2d5d986 100644 --- a/Source/Core/AudioCommon/WASAPIStream.h +++ b/Source/Core/AudioCommon/WASAPIStream.h @@ -5,16 +5,19 @@ #pragma once #ifdef _WIN32 + // clang-format off #include #include +#include +#include // clang-format on -#endif #include #include #include #include +#include #include "AudioCommon/SoundStream.h" @@ -23,6 +26,8 @@ struct IAudioRenderClient; struct IMMDevice; struct IMMDeviceEnumerator; +#endif + class WASAPIStream final : public SoundStream { #ifdef _WIN32 @@ -35,7 +40,7 @@ public: static bool isValid(); static std::vector GetAvailableDevices(); - static IMMDevice* GetDeviceByName(std::string name); + static Microsoft::WRL::ComPtr GetDeviceByName(std::string name); private: u32 m_frames_in_buffer = 0; @@ -43,10 +48,14 @@ private: std::atomic m_stopped = false; std::thread m_thread; - IAudioClient* m_audio_client = nullptr; - IAudioRenderClient* m_audio_renderer = nullptr; - IMMDeviceEnumerator* m_enumerator = nullptr; - HANDLE m_need_data_event = nullptr; + // CoUninitialize must be called after all WASAPI COM objects have been destroyed, + // therefore this member must be located before them, as first class fields are destructed last + wil::unique_couninitialize_call m_coinitialize{false}; + + Microsoft::WRL::ComPtr m_enumerator; + Microsoft::WRL::ComPtr m_audio_client; + Microsoft::WRL::ComPtr m_audio_renderer; + wil::unique_event_nothrow m_need_data_event; WAVEFORMATEXTENSIBLE m_format; #endif // _WIN32 }; -- cgit v1.2.3 From ee60be45010fed98a3d28f736bcf00efb036560c Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 17 Aug 2019 10:08:16 +0200 Subject: AudioCommon/WASAPI: Simplify thread synchronization model by not detaching WASAPI handler thread --- Source/Core/AudioCommon/WASAPIStream.h | 1 - 1 file changed, 1 deletion(-) (limited to 'Source/Core/AudioCommon/WASAPIStream.h') diff --git a/Source/Core/AudioCommon/WASAPIStream.h b/Source/Core/AudioCommon/WASAPIStream.h index 39d2d5d986..b4337a378a 100644 --- a/Source/Core/AudioCommon/WASAPIStream.h +++ b/Source/Core/AudioCommon/WASAPIStream.h @@ -45,7 +45,6 @@ public: private: u32 m_frames_in_buffer = 0; std::atomic m_running = false; - std::atomic m_stopped = false; std::thread m_thread; // CoUninitialize must be called after all WASAPI COM objects have been destroyed, -- cgit v1.2.3 From 5dbbf36563ce5a75e84f58f000d45e3b4c1ab82d Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 17 Aug 2019 11:05:33 +0200 Subject: AudioCommon/WASAPI: Use std::string_view where applicable --- Source/Core/AudioCommon/WASAPIStream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/AudioCommon/WASAPIStream.h') diff --git a/Source/Core/AudioCommon/WASAPIStream.h b/Source/Core/AudioCommon/WASAPIStream.h index b4337a378a..640d0155fc 100644 --- a/Source/Core/AudioCommon/WASAPIStream.h +++ b/Source/Core/AudioCommon/WASAPIStream.h @@ -40,7 +40,7 @@ public: static bool isValid(); static std::vector GetAvailableDevices(); - static Microsoft::WRL::ComPtr GetDeviceByName(std::string name); + static Microsoft::WRL::ComPtr GetDeviceByName(std::string_view name); private: u32 m_frames_in_buffer = 0; -- cgit v1.2.3