diff options
-rw-r--r-- | alc/backends/dsound.cpp | 12 | ||||
-rw-r--r-- | alc/backends/wasapi.cpp | 46 | ||||
-rw-r--r-- | common/comptr.h | 38 |
3 files changed, 62 insertions, 34 deletions
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp index b5596f1c..58aa69b2 100644 --- a/alc/backends/dsound.cpp +++ b/alc/backends/dsound.cpp @@ -307,12 +307,10 @@ void DSoundPlayback::open(std::string_view name) if(PlaybackDevices.empty()) { /* Initialize COM to prevent name truncation */ - HRESULT hrcom{CoInitialize(nullptr)}; + ComWrapper com{}; hr = DirectSoundEnumerateW(DSoundEnumDevices, &PlaybackDevices); if(FAILED(hr)) ERR("Error enumerating DirectSound devices (0x%lx)!\n", hr); - if(SUCCEEDED(hrcom)) - CoUninitialize(); } const GUID *guid{nullptr}; @@ -583,12 +581,10 @@ void DSoundCapture::open(std::string_view name) if(CaptureDevices.empty()) { /* Initialize COM to prevent name truncation */ - HRESULT hrcom{CoInitialize(nullptr)}; + ComWrapper com{}; hr = DirectSoundCaptureEnumerateW(DSoundEnumDevices, &CaptureDevices); if(FAILED(hr)) ERR("Error enumerating DirectSound devices (0x%lx)!\n", hr); - if(SUCCEEDED(hrcom)) - CoUninitialize(); } const GUID *guid{nullptr}; @@ -815,8 +811,8 @@ std::string DSoundBackendFactory::probe(BackendType type) }; /* Initialize COM to prevent name truncation */ + ComWrapper com{}; HRESULT hr; - HRESULT hrcom{CoInitialize(nullptr)}; switch(type) { case BackendType::Playback: @@ -835,8 +831,6 @@ std::string DSoundBackendFactory::probe(BackendType type) std::for_each(CaptureDevices.cbegin(), CaptureDevices.cend(), add_device); break; } - if(SUCCEEDED(hrcom)) - CoUninitialize(); return outnames; } diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp index 71975b55..62c4c58a 100644 --- a/alc/backends/wasapi.cpp +++ b/alc/backends/wasapi.cpp @@ -973,15 +973,15 @@ int WasapiProxy::messageHandler(std::promise<HRESULT> *promise) { TRACE("Starting message thread\n"); - HRESULT hr{CoInitializeEx(nullptr, COINIT_MULTITHREADED)}; - if(FAILED(hr)) + ComWrapper com{COINIT_MULTITHREADED}; + if(!com) { - WARN("Failed to initialize COM: 0x%08lx\n", hr); - promise->set_value(hr); + WARN("Failed to initialize COM: 0x%08lx\n", com.status()); + promise->set_value(com.status()); return 0; } - hr = sDeviceHelper.emplace().init(); + HRESULT hr{sDeviceHelper.emplace().init()}; promise->set_value(hr); promise = nullptr; if(FAILED(hr)) @@ -1040,7 +1040,6 @@ int WasapiProxy::messageHandler(std::promise<HRESULT> *promise) skip_loop: sDeviceHelper.reset(); - CoUninitialize(); return 0; } @@ -1113,11 +1112,11 @@ WasapiPlayback::~WasapiPlayback() FORCE_ALIGN int WasapiPlayback::mixerProc() { - HRESULT hr{CoInitializeEx(nullptr, COINIT_MULTITHREADED)}; - if(FAILED(hr)) + ComWrapper com{COINIT_MULTITHREADED}; + if(!com) { - ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", hr); - mDevice->handleDisconnect("COM init failed: 0x%08lx", hr); + ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", com.status()); + mDevice->handleDisconnect("COM init failed: 0x%08lx", com.status()); return 1; } @@ -1135,7 +1134,7 @@ FORCE_ALIGN int WasapiPlayback::mixerProc() while(!mKillNow.load(std::memory_order_relaxed)) { UINT32 written; - hr = audio.mClient->GetCurrentPadding(&written); + HRESULT hr{audio.mClient->GetCurrentPadding(&written)}; if(FAILED(hr)) { ERR("Failed to get padding: 0x%08lx\n", hr); @@ -1194,17 +1193,16 @@ FORCE_ALIGN int WasapiPlayback::mixerProc() } mPadding.store(0u, std::memory_order_release); - CoUninitialize(); return 0; } FORCE_ALIGN int WasapiPlayback::mixerSpatialProc() { - HRESULT hr{CoInitializeEx(nullptr, COINIT_MULTITHREADED)}; - if(FAILED(hr)) + ComWrapper com{COINIT_MULTITHREADED}; + if(!com) { - ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", hr); - mDevice->handleDisconnect("COM init failed: 0x%08lx", hr); + ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", com.status()); + mDevice->handleDisconnect("COM init failed: 0x%08lx", com.status()); return 1; } @@ -1231,7 +1229,7 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc() { ERR("WaitForSingleObjectEx error: 0x%lx\n", res); - hr = audio.mRender->Reset(); + HRESULT hr{audio.mRender->Reset()}; if(FAILED(hr)) { ERR("ISpatialAudioObjectRenderStream::Reset failed: 0x%08lx\n", hr); @@ -1241,7 +1239,7 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc() } UINT32 dynamicCount{}, framesToDo{}; - hr = audio.mRender->BeginUpdatingAudioObjects(&dynamicCount, &framesToDo); + HRESULT hr{audio.mRender->BeginUpdatingAudioObjects(&dynamicCount, &framesToDo)}; if(SUCCEEDED(hr)) { if(channels.empty()) UNLIKELY @@ -1310,7 +1308,6 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc() } mPadding.store(0u, std::memory_order_release); - CoUninitialize(); return 0; } @@ -2150,11 +2147,11 @@ WasapiCapture::~WasapiCapture() FORCE_ALIGN int WasapiCapture::recordProc() { - HRESULT hr{CoInitializeEx(nullptr, COINIT_MULTITHREADED)}; - if(FAILED(hr)) + ComWrapper com{COINIT_MULTITHREADED}; + if(!com) { - ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", hr); - mDevice->handleDisconnect("COM init failed: 0x%08lx", hr); + ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", com.status()); + mDevice->handleDisconnect("COM init failed: 0x%08lx", com.status()); return 1; } @@ -2164,7 +2161,7 @@ FORCE_ALIGN int WasapiCapture::recordProc() while(!mKillNow.load(std::memory_order_relaxed)) { UINT32 avail; - hr = mCapture->GetNextPacketSize(&avail); + HRESULT hr{mCapture->GetNextPacketSize(&avail)}; if(FAILED(hr)) ERR("Failed to get next packet size: 0x%08lx\n", hr); else if(avail > 0) @@ -2235,7 +2232,6 @@ FORCE_ALIGN int WasapiCapture::recordProc() ERR("WaitForSingleObjectEx error: 0x%lx\n", res); } - CoUninitialize(); return 0; } diff --git a/common/comptr.h b/common/comptr.h index 5a733ea2..9f8fd294 100644 --- a/common/comptr.h +++ b/common/comptr.h @@ -7,6 +7,44 @@ #include <utility> #include <variant> +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <objbase.h> + +struct ComWrapper { + HRESULT mStatus{}; + + ComWrapper(void *reserved, DWORD coinit) + : mStatus{CoInitializeEx(reserved, coinit)} + { } + ComWrapper(DWORD coinit=COINIT_APARTMENTTHREADED) + : mStatus{CoInitializeEx(nullptr, coinit)} + { } + ComWrapper(ComWrapper&& rhs) { mStatus = std::exchange(rhs.mStatus, E_FAIL); } + ComWrapper(const ComWrapper&) = delete; + ~ComWrapper() { if(SUCCEEDED(mStatus)) CoUninitialize(); } + + ComWrapper& operator=(ComWrapper&& rhs) + { + if(SUCCEEDED(mStatus)) + CoUninitialize(); + mStatus = std::exchange(rhs.mStatus, E_FAIL); + return *this; + } + ComWrapper& operator=(const ComWrapper&) = delete; + + HRESULT status() const noexcept { return mStatus; } + explicit operator bool() const noexcept { return SUCCEEDED(status()); } + + void uninit() + { + if(SUCCEEDED(mStatus)) + CoUninitialize(); + mStatus = E_FAIL; + } +}; + + template<typename T> struct ComPtr { using element_type = T; |