From bc965f31329dd8234c43547d1d523bee781c1f20 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Thu, 30 Sep 2021 14:49:13 -0700 Subject: [PATCH 1/4] simpler --- strings/base_agile_ref.h | 7 ++++++- test/test_component_base/pch.h | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/strings/base_agile_ref.h b/strings/base_agile_ref.h index f76f6b0c2..eb5bfe245 100644 --- a/strings/base_agile_ref.h +++ b/strings/base_agile_ref.h @@ -3,7 +3,7 @@ WINRT_EXPORT namespace winrt { #if defined (WINRT_NO_MODULE_LOCK) - // Defining WINRT_NO_MODULE_LOCK is appropriate for apps (executables) that don't implement something like DllCanUnloadNow + // Defining WINRT_NO_MODULE_LOCK is appropriate for apps (executables) or pinned DLLs (that don't support unloading) // and can thus avoid the synchronization overhead imposed by the default module lock. constexpr auto get_module_lock() noexcept @@ -19,6 +19,11 @@ WINRT_EXPORT namespace winrt { return 0; } + + constexpr explicit operator bool() noexcept + { + return true; + } }; return lock{}; diff --git a/test/test_component_base/pch.h b/test/test_component_base/pch.h index 6f70f09be..e5c39a869 100644 --- a/test/test_component_base/pch.h +++ b/test/test_component_base/pch.h @@ -1 +1,9 @@ #pragma once + +#define WINRT_NO_MODULE_LOCK +#include "winrt/base.h" + +// get_module_lock will always return true if WINRT_NO_MODULE_LOCK is defined. +// This ensures that if the DLL unecessarily exports DllCanUnloadNow that it +// will in turn return S_FALSE. +static_assert(winrt::get_module_lock()); From 6c513c890c14ed1928943401eeafa88fbefa5f8e Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Thu, 30 Sep 2021 14:58:07 -0700 Subject: [PATCH 2/4] test pinning --- test/test_module_lock_none/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_module_lock_none/main.cpp b/test/test_module_lock_none/main.cpp index 1a4b19fa7..21b1b0e57 100644 --- a/test/test_module_lock_none/main.cpp +++ b/test/test_module_lock_none/main.cpp @@ -1,5 +1,6 @@ #define CATCH_CONFIG_RUNNER #include "catch.hpp" +#include // Defining WINRT_NO_MODULE_LOCK means that winrt::get_module_lock is not defined and calls to it are elided from C++/WinRT. // This is an optimization for apps (executables) that don't implement something like DllCanUnloadNow. @@ -52,6 +53,11 @@ TEST_CASE("module_lock_none") winrt::clear_factory_cache(); REQUIRE(first == second); + + // Validates that test_component_base is pinned by virtue of it defining WINRT_NO_MODULE_LOCK. + + auto can_unload = reinterpret_cast(GetProcAddress(LoadLibraryA("test_component_base.dll"), "DllCanUnloadNow")); + REQUIRE(can_unload() == S_FALSE); } int main(int const argc, char** argv) From 8adccd6fae03ef2c699e58d16704a9d129cbf659 Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Thu, 30 Sep 2021 15:03:56 -0700 Subject: [PATCH 3/4] test inverse --- test/test_module_lock_none/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_module_lock_none/main.cpp b/test/test_module_lock_none/main.cpp index 21b1b0e57..6fb4d379f 100644 --- a/test/test_module_lock_none/main.cpp +++ b/test/test_module_lock_none/main.cpp @@ -58,6 +58,9 @@ TEST_CASE("module_lock_none") auto can_unload = reinterpret_cast(GetProcAddress(LoadLibraryA("test_component_base.dll"), "DllCanUnloadNow")); REQUIRE(can_unload() == S_FALSE); + + auto cannot_unload = reinterpret_cast(GetProcAddress(LoadLibraryA("test_component_derived.dll"), "DllCanUnloadNow")); + REQUIRE(cannot_unload() == S_OK); } int main(int const argc, char** argv) From b00bb22b6ed0031ee473a2b47e56beac754ae7fe Mon Sep 17 00:00:00 2001 From: Kenny Kerr Date: Thu, 30 Sep 2021 15:35:01 -0700 Subject: [PATCH 4/4] deps --- cppwinrt.sln | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cppwinrt.sln b/cppwinrt.sln index d2141707c..e3ce40f95 100644 --- a/cppwinrt.sln +++ b/cppwinrt.sln @@ -87,6 +87,8 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_module_lock_none", "test\test_module_lock_none\test_module_lock_none.vcxproj", "{D48A96C2-8512-4CC3-B6E4-7CFF07ED8ED3}" ProjectSection(ProjectDependencies) = postProject {D613FB39-5035-4043-91E2-BAB323908AF4} = {D613FB39-5035-4043-91E2-BAB323908AF4} + {13333A6F-6A4A-48CD-865C-0F65135EB018} = {13333A6F-6A4A-48CD-865C-0F65135EB018} + {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E} = {0080F6D1-AEC3-4F89-ADE1-3D22A7EBF99E} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_module_lock_custom", "test\test_module_lock_custom\test_module_lock_custom.vcxproj", "{08C40663-B6A3-481E-8755-AE32BAD99501}"