Skip to content

Commit 6270dcc

Browse files
authored
Optimize factory caching for apps and pinned DLLs (#1031)
1 parent ae411cc commit 6270dcc

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

strings/base_activation.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,19 +233,23 @@ namespace winrt::impl
233233

234234
explicit factory_count_guard(size_t& count) noexcept : m_count(count)
235235
{
236+
#ifndef WINRT_NO_MODULE_LOCK
236237
#ifdef _WIN64
237238
_InterlockedIncrement64((int64_t*)&m_count);
238239
#else
239240
_InterlockedIncrement((long*)&m_count);
241+
#endif
240242
#endif
241243
}
242244

243245
~factory_count_guard() noexcept
244246
{
247+
#ifndef WINRT_NO_MODULE_LOCK
245248
#ifdef _WIN64
246249
_InterlockedDecrement64((int64_t*)&m_count);
247250
#else
248251
_InterlockedDecrement((long*)&m_count);
252+
#endif
249253
#endif
250254
}
251255

@@ -362,7 +366,9 @@ namespace winrt::impl
362366
if (nullptr == _InterlockedCompareExchangePointer(reinterpret_cast<void**>(&m_value.object), *reinterpret_cast<void**>(&object), nullptr))
363367
{
364368
*reinterpret_cast<void**>(&object) = nullptr;
369+
#ifndef WINRT_NO_MODULE_LOCK
365370
get_factory_cache().add(this);
371+
#endif
366372
}
367373

368374
return callback(*reinterpret_cast<com_ref<Interface> const*>(&m_value.object));

test/test_module_lock_none/main.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#define WINRT_NO_MODULE_LOCK
88
#include "winrt/Windows.Foundation.h"
9+
#include "winrt/Windows.System.Diagnostics.h"
910

1011
namespace
1112
{
@@ -26,9 +27,31 @@ TEST_CASE("module_lock_none")
2627
REQUIRE(--winrt::get_module_lock() == 0);
2728
REQUIRE(--winrt::get_module_lock() == 0);
2829

29-
// Just validates that you can still construct an implementation without a module lock.
30+
// Validates that you can still construct an implementation without a module lock.
3031

3132
winrt::make<FastStringable>();
33+
34+
// Validates that clear_factory_cache is still callable, but has no effect.
35+
// Windows.System.Diagnostics is used because it is implemented in C++/WinRT that
36+
// unlike WRL, does not cache factories inside the implementation. Client-side
37+
// caching is far more effective.
38+
39+
void* first = nullptr;
40+
void* second = nullptr;
41+
42+
{
43+
auto factory = winrt::get_activation_factory<winrt::Windows::System::Diagnostics::SystemDiagnosticInfo>();
44+
first = winrt::get_abi(factory);
45+
}
46+
winrt::clear_factory_cache();
47+
48+
{
49+
auto factory = winrt::get_activation_factory<winrt::Windows::System::Diagnostics::SystemDiagnosticInfo>();
50+
second = winrt::get_abi(factory);
51+
}
52+
winrt::clear_factory_cache();
53+
54+
REQUIRE(first == second);
3255
}
3356

3457
int main(int const argc, char** argv)

0 commit comments

Comments
 (0)