diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 26783b81aa..322ba30cd1 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -123,6 +123,7 @@ deliveryoptimization deliveryoptimizationerrors DENYWR desktopappinstaller +devblogs devhome DFX dic diff --git a/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp b/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp index 3f0dd03471..38a15f003a 100644 --- a/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp +++ b/src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp @@ -262,6 +262,43 @@ namespace AppInstaller::Repository::Microsoft struct CachedInstalledIndex { + // https://devblogs.microsoft.com/oldnewthing/20210215-00/?p=104865 + struct Singleton + { + struct Holder : public winrt::implements + { + static constexpr std::wstring_view Guid{ L"{48c47064-4fff-4eca-812c-dbb4f33a8fcb}" }; + std::shared_ptr m_shared{ std::make_shared() }; + }; + + std::weak_ptr m_weak; + winrt::slim_mutex m_lock; + + std::shared_ptr Get() + { + { + const std::shared_lock lock{ m_lock }; + if (auto cachedIndex = m_weak.lock()) + { + return cachedIndex; + } + } + + auto value = winrt::make_self(); + + const std::shared_lock lock{ m_lock }; + if (auto cachedIndex = m_weak.lock()) + { + return cachedIndex; + } + + winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().Insert(Holder::Guid, value.as()); + + m_weak = value->m_shared; + return value->m_shared; + } + }; + CachedInstalledIndex() { ARPHelper arpHelper; @@ -340,7 +377,7 @@ namespace AppInstaller::Repository::Microsoft if (PredefinedInstalledSourceFactory::StringToFilter(m_details.Arg) == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate) { - GetCachedInstalledIndex().ForceNextUpdate(); + GetCachedInstalledIndex()->ForceNextUpdate(); } } @@ -359,9 +396,9 @@ namespace AppInstaller::Repository::Microsoft // Only cache for the unfiltered install data if (filter == PredefinedInstalledSourceFactory::Filter::None || filter == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate) { - CachedInstalledIndex& cachedIndex = GetCachedInstalledIndex(); - cachedIndex.UpdateIndexIfNeeded(); - return std::make_shared(m_details, cachedIndex.GetCopy(), true); + std::shared_ptr cachedIndex = GetCachedInstalledIndex(); + cachedIndex->UpdateIndexIfNeeded(); + return std::make_shared(m_details, cachedIndex->GetCopy(), true); } else { @@ -370,10 +407,10 @@ namespace AppInstaller::Repository::Microsoft } private: - CachedInstalledIndex& GetCachedInstalledIndex() + std::shared_ptr GetCachedInstalledIndex() { - static CachedInstalledIndex s_installedIndex; - return s_installedIndex; + static CachedInstalledIndex::Singleton s_installedIndex; + return s_installedIndex.Get(); } SourceDetails m_details; diff --git a/src/AppInstallerRepositoryCore/pch.h b/src/AppInstallerRepositoryCore/pch.h index 753bb07340..1fe0660b64 100644 --- a/src/AppInstallerRepositoryCore/pch.h +++ b/src/AppInstallerRepositoryCore/pch.h @@ -21,7 +21,8 @@ #include -#include +#include +#include #include #include #include @@ -41,7 +42,8 @@ #include #include #include -#include +#include +#include #include #include #include