From e4526ed7236a68c6ed31bf93f28fad24910e24d6 Mon Sep 17 00:00:00 2001 From: benstevens48 Date: Wed, 17 Feb 2021 19:47:30 +0000 Subject: [PATCH] add thread safety using call_once --- winrt/lib/images/CanvasBitmap.cpp | 5 +++-- winrt/lib/images/CanvasImage.cpp | 5 ++--- winrt/lib/images/CanvasImage.h | 1 + winrt/lib/images/WicAdapter.h | 8 ++++---- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/winrt/lib/images/CanvasBitmap.cpp b/winrt/lib/images/CanvasBitmap.cpp index 38aaefa5a..c93b1586a 100644 --- a/winrt/lib/images/CanvasBitmap.cpp +++ b/winrt/lib/images/CanvasBitmap.cpp @@ -272,8 +272,9 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas WicBitmapSource DefaultBitmapAdapter::CreateWicBitmapSource(ICanvasDevice* device, IStream* fileStream, bool tryEnableIndexing) { + auto factory = m_wicAdapter->GetFactory(); ComPtr wicBitmapDecoder; - ThrowIfFailed(m_wicAdapter->GetFactory()->CreateDecoderFromStream( + ThrowIfFailed(factory->CreateDecoderFromStream( fileStream, nullptr, WICDecodeMetadataCacheOnDemand, @@ -310,7 +311,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas auto transformOptions = GetTransformOptionsFromPhotoOrientation(orientation); ComPtr wicFormatConverter; - ThrowIfFailed(m_wicAdapter->GetFactory()->CreateFormatConverter(&wicFormatConverter)); + ThrowIfFailed(factory->CreateFormatConverter(&wicFormatConverter)); auto targetPixelFormat = GUID_WICPixelFormat32bppPBGRA; diff --git a/winrt/lib/images/CanvasImage.cpp b/winrt/lib/images/CanvasImage.cpp index 88f63ac75..bef76494f 100644 --- a/winrt/lib/images/CanvasImage.cpp +++ b/winrt/lib/images/CanvasImage.cpp @@ -406,12 +406,11 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas ComPtr const& DefaultCanvasImageAdapter::GetFactory() { - if (!m_wicAdapter) - { + std::call_once(m_initWicAdapterFlag, [this] { // Hold on to the wic adapter so it doesn't keep getting destroyed // and recreated. m_wicAdapter = WicAdapter::GetInstance(); - } + }); return m_wicAdapter->GetFactory(); } diff --git a/winrt/lib/images/CanvasImage.h b/winrt/lib/images/CanvasImage.h index 2933009ac..7e4cf9362 100644 --- a/winrt/lib/images/CanvasImage.h +++ b/winrt/lib/images/CanvasImage.h @@ -94,6 +94,7 @@ namespace ABI { namespace Microsoft { namespace Graphics { namespace Canvas class DefaultCanvasImageAdapter : public CanvasImageAdapter { std::shared_ptr m_wicAdapter; + std::once_flag m_initWicAdapterFlag; public: virtual ComPtr RunAsync(std::function&& fn) override; diff --git a/winrt/lib/images/WicAdapter.h b/winrt/lib/images/WicAdapter.h index 3abc345fd..2a511ab2e 100644 --- a/winrt/lib/images/WicAdapter.h +++ b/winrt/lib/images/WicAdapter.h @@ -21,6 +21,7 @@ class WicAdapter : public Singleton class DefaultWicAdapter : public WicAdapter { ComPtr m_wicFactory; + std::once_flag m_initFactoryFlag; public: DefaultWicAdapter() @@ -29,15 +30,14 @@ class DefaultWicAdapter : public WicAdapter virtual ComPtr const& GetFactory() override { - if (!m_wicFactory) - { + std::call_once(m_initFactoryFlag, [this] { ThrowIfFailed( CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&m_wicFactory))); - } + IID_PPV_ARGS(&m_wicFactory))); + }); return m_wicFactory; }