Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions strings/base_activation.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,19 +233,23 @@ namespace winrt::impl

explicit factory_count_guard(size_t& count) noexcept : m_count(count)
{
#ifndef WINRT_NO_MODULE_LOCK
#ifdef _WIN64
_InterlockedIncrement64((int64_t*)&m_count);
#else
_InterlockedIncrement((long*)&m_count);
#endif
#endif
}

~factory_count_guard() noexcept
{
#ifndef WINRT_NO_MODULE_LOCK
#ifdef _WIN64
_InterlockedDecrement64((int64_t*)&m_count);
#else
_InterlockedDecrement((long*)&m_count);
#endif
#endif
}

Expand Down Expand Up @@ -362,7 +366,9 @@ namespace winrt::impl
if (nullptr == _InterlockedCompareExchangePointer(reinterpret_cast<void**>(&m_value.object), *reinterpret_cast<void**>(&object), nullptr))
{
*reinterpret_cast<void**>(&object) = nullptr;
#ifndef WINRT_NO_MODULE_LOCK
get_factory_cache().add(this);
#endif
}

return callback(*reinterpret_cast<com_ref<Interface> const*>(&m_value.object));
Expand Down
25 changes: 24 additions & 1 deletion test/test_module_lock_none/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#define WINRT_NO_MODULE_LOCK
#include "winrt/Windows.Foundation.h"
#include "winrt/Windows.System.Diagnostics.h"

namespace
{
Expand All @@ -26,9 +27,31 @@ TEST_CASE("module_lock_none")
REQUIRE(--winrt::get_module_lock() == 0);
REQUIRE(--winrt::get_module_lock() == 0);

// Just validates that you can still construct an implementation without a module lock.
// Validates that you can still construct an implementation without a module lock.

winrt::make<FastStringable>();

// Validates that clear_factory_cache is still callable, but has no effect.
// Windows.System.Diagnostics is used because it is implemented in C++/WinRT that
// unlike WRL, does not cache factories inside the implementation. Client-side
// caching is far more effective.

void* first = nullptr;
void* second = nullptr;

{
auto factory = winrt::get_activation_factory<winrt::Windows::System::Diagnostics::SystemDiagnosticInfo>();
first = winrt::get_abi(factory);
}
winrt::clear_factory_cache();

{
auto factory = winrt::get_activation_factory<winrt::Windows::System::Diagnostics::SystemDiagnosticInfo>();
second = winrt::get_abi(factory);
}
winrt::clear_factory_cache();

REQUIRE(first == second);
}

int main(int const argc, char** argv)
Expand Down