From d2de52f818909517053dc7be62b46368146b1d38 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Sat, 12 Oct 2019 18:03:54 +0200 Subject: [PATCH] [AFV] Ref T730, use CoInitializeEx on windows for threaded CAfvClient --- src/blackcore/afv/clients/afvclient.cpp | 28 +++++++++++++++++++++++++ src/blackcore/afv/clients/afvclient.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/src/blackcore/afv/clients/afvclient.cpp b/src/blackcore/afv/clients/afvclient.cpp index 242b4b777..a9fdd6fee 100644 --- a/src/blackcore/afv/clients/afvclient.cpp +++ b/src/blackcore/afv/clients/afvclient.cpp @@ -674,9 +674,37 @@ namespace BlackCore void CAfvClient::initialize() { +#ifdef _WIN32 + if (!m_winCoInitialized) + { + HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + // RPC_E_CHANGED_MODE: CoInitializeEx was already called by someone else in this thread with a different mode. + if (hr == RPC_E_CHANGED_MODE) + { + CLogMessage(this).debug(u"CoInitializeEx was already called with a different mode. Trying again."); + hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + } + + // S_OK: The COM library was initialized successfully on this thread. + // S_FALSE: The COM library is already initialized on this thread. Reference count was incremented. This is not an error. + if (hr == S_OK || hr == S_FALSE) { m_winCoInitialized = true; } + } +#endif CLogMessage(this).info(u"Initialize AFV client in thread: %1") << CThreadUtils::threadInfo(this->thread()); } + void CAfvClient::cleanup() + { +#ifdef _WIN32 + if (m_winCoInitialized) + { + CoUninitialize(); + m_winCoInitialized = false; + } +#endif + } + void CAfvClient::onPositionUpdateTimer() { if (hasContext()) diff --git a/src/blackcore/afv/clients/afvclient.h b/src/blackcore/afv/clients/afvclient.h index 5dcb8ff87..a7d9b7719 100644 --- a/src/blackcore/afv/clients/afvclient.h +++ b/src/blackcore/afv/clients/afvclient.h @@ -244,6 +244,9 @@ namespace BlackCore //! \copydoc BlackMisc::CContinuousWorker::initialize virtual void initialize() override; + //! \copydoc BlackMisc::CContinuousWorker::cleanup + virtual void cleanup() override; + private: void opusDataAvailable(const Audio::OpusDataAvailableArgs &args); void audioOutDataAvailable(const AudioRxOnTransceiversDto &dto); @@ -292,6 +295,7 @@ namespace BlackCore std::atomic_bool m_isStarted { false }; std::atomic_bool m_loopbackOn { false }; + std::atomic_bool m_winCoInitialized { false }; //!< Windows only CoInitializeEx QDateTime m_startDateTimeUtc; double m_inputVolumeDb;