Skip to content

Commit a7f7c21

Browse files
authored
Use atomic functions to ensure single initialization of tracking catalog (#4592)
Fixes #4587 ## Change Hold the tracking catalog object in a `shared_ptr` and use the atomic functions to ensure that only one thread can initialize it.
1 parent 986f240 commit a7f7c21

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

src/AppInstallerRepositoryCore/Public/winget/RepositorySource.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,6 @@ namespace AppInstaller::Repository
344344
bool m_isComposite = false;
345345
std::optional<TimeSpan> m_backgroundUpdateInterval;
346346
bool m_installedPackageInformationOnly = false;
347-
mutable PackageTrackingCatalog m_trackingCatalog;
347+
mutable std::shared_ptr<PackageTrackingCatalog> m_trackingCatalog;
348348
};
349349
}

src/AppInstallerRepositoryCore/RepositorySource.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -983,12 +983,19 @@ namespace AppInstaller::Repository
983983

984984
PackageTrackingCatalog Source::GetTrackingCatalog() const
985985
{
986-
if (!m_trackingCatalog)
986+
// With C++20, consider removing the shared_ptr here and making the one inside PackageTrackingCatalog atomic.
987+
std::shared_ptr<PackageTrackingCatalog> currentTrackingCatalog = std::atomic_load(&m_trackingCatalog);
988+
if (!currentTrackingCatalog)
987989
{
988-
m_trackingCatalog = PackageTrackingCatalog::CreateForSource(*this);
990+
std::shared_ptr<PackageTrackingCatalog> newTrackingCatalog = std::make_shared<PackageTrackingCatalog>(PackageTrackingCatalog::CreateForSource(*this));
991+
992+
if (std::atomic_compare_exchange_strong(&m_trackingCatalog, &currentTrackingCatalog, newTrackingCatalog))
993+
{
994+
currentTrackingCatalog = newTrackingCatalog;
995+
}
989996
}
990997

991-
return m_trackingCatalog;
998+
return *currentTrackingCatalog;
992999
}
9931000

9941001
std::vector<SourceDetails> Source::GetCurrentSources()

0 commit comments

Comments
 (0)