Skip to content

Commit 326558c

Browse files
authored
Fix crash due to static weak pointer referencing an object in an unloaded DLL (microsoft#5474)
Based on https://devblogs.microsoft.com/oldnewthing/20210215-00/
1 parent 68e3fc2 commit 326558c

File tree

3 files changed

+49
-9
lines changed

3 files changed

+49
-9
lines changed

.github/actions/spelling/expect.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ deliveryoptimization
123123
deliveryoptimizationerrors
124124
DENYWR
125125
desktopappinstaller
126+
devblogs
126127
devhome
127128
DFX
128129
dic

src/AppInstallerRepositoryCore/Microsoft/PredefinedInstalledSourceFactory.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,43 @@ namespace AppInstaller::Repository::Microsoft
262262

263263
struct CachedInstalledIndex
264264
{
265+
// https://devblogs.microsoft.com/oldnewthing/20210215-00/?p=104865
266+
struct Singleton
267+
{
268+
struct Holder : public winrt::implements<Holder, winrt::Windows::Foundation::IInspectable>
269+
{
270+
static constexpr std::wstring_view Guid{ L"{48c47064-4fff-4eca-812c-dbb4f33a8fcb}" };
271+
std::shared_ptr<CachedInstalledIndex> m_shared{ std::make_shared<CachedInstalledIndex>() };
272+
};
273+
274+
std::weak_ptr<CachedInstalledIndex> m_weak;
275+
winrt::slim_mutex m_lock;
276+
277+
std::shared_ptr<CachedInstalledIndex> Get()
278+
{
279+
{
280+
const std::shared_lock lock{ m_lock };
281+
if (auto cachedIndex = m_weak.lock())
282+
{
283+
return cachedIndex;
284+
}
285+
}
286+
287+
auto value = winrt::make_self<Holder>();
288+
289+
const std::shared_lock lock{ m_lock };
290+
if (auto cachedIndex = m_weak.lock())
291+
{
292+
return cachedIndex;
293+
}
294+
295+
winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().Insert(Holder::Guid, value.as<winrt::Windows::Foundation::IInspectable>());
296+
297+
m_weak = value->m_shared;
298+
return value->m_shared;
299+
}
300+
};
301+
265302
CachedInstalledIndex()
266303
{
267304
ARPHelper arpHelper;
@@ -340,7 +377,7 @@ namespace AppInstaller::Repository::Microsoft
340377

341378
if (PredefinedInstalledSourceFactory::StringToFilter(m_details.Arg) == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate)
342379
{
343-
GetCachedInstalledIndex().ForceNextUpdate();
380+
GetCachedInstalledIndex()->ForceNextUpdate();
344381
}
345382
}
346383

@@ -359,9 +396,9 @@ namespace AppInstaller::Repository::Microsoft
359396
// Only cache for the unfiltered install data
360397
if (filter == PredefinedInstalledSourceFactory::Filter::None || filter == PredefinedInstalledSourceFactory::Filter::NoneWithForcedCacheUpdate)
361398
{
362-
CachedInstalledIndex& cachedIndex = GetCachedInstalledIndex();
363-
cachedIndex.UpdateIndexIfNeeded();
364-
return std::make_shared<SQLiteIndexSource>(m_details, cachedIndex.GetCopy(), true);
399+
std::shared_ptr<CachedInstalledIndex> cachedIndex = GetCachedInstalledIndex();
400+
cachedIndex->UpdateIndexIfNeeded();
401+
return std::make_shared<SQLiteIndexSource>(m_details, cachedIndex->GetCopy(), true);
365402
}
366403
else
367404
{
@@ -370,10 +407,10 @@ namespace AppInstaller::Repository::Microsoft
370407
}
371408

372409
private:
373-
CachedInstalledIndex& GetCachedInstalledIndex()
410+
std::shared_ptr<CachedInstalledIndex> GetCachedInstalledIndex()
374411
{
375-
static CachedInstalledIndex s_installedIndex;
376-
return s_installedIndex;
412+
static CachedInstalledIndex::Singleton s_installedIndex;
413+
return s_installedIndex.Get();
377414
}
378415

379416
SourceDetails m_details;

src/AppInstallerRepositoryCore/pch.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
#include <winsqlite/winsqlite3.h>
2323

24-
#include <winrt/Windows.ApplicationModel.h>
24+
#include <winrt/Windows.ApplicationModel.h>
25+
#include <winrt/Windows.ApplicationModel.Core.h>
2526
#include <winrt/Windows.Foundation.h>
2627
#include <winrt/Windows.Foundation.Collections.h>
2728
#include <winrt/Windows.Management.Deployment.h>
@@ -41,7 +42,8 @@
4142
#include <memory>
4243
#include <optional>
4344
#include <random>
44-
#include <set>
45+
#include <set>
46+
#include <shared_mutex>
4547
#include <string>
4648
#include <string_view>
4749
#include <sstream>

0 commit comments

Comments
 (0)