Skip to content

Commit 297365e

Browse files
authored
Can clear a specific factory from static lifetime store (#654)
1 parent 4e32538 commit 297365e

File tree

3 files changed

+54
-13
lines changed

3 files changed

+54
-13
lines changed

strings/base_abi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ namespace winrt::impl
7070
virtual int32_t __stdcall unused2() noexcept = 0;
7171
virtual int32_t __stdcall unused3() noexcept = 0;
7272
virtual int32_t __stdcall Insert(void*, void*, bool*) noexcept = 0;
73+
virtual int32_t __stdcall Remove(void*) noexcept = 0;
7374
virtual int32_t __stdcall unused4() noexcept = 0;
74-
virtual int32_t __stdcall unused5() noexcept = 0;
7575
};
7676

7777
struct __declspec(novtable) IWeakReference : unknown_abi

strings/base_implements.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,14 @@ namespace winrt::impl
11981198
};
11991199
#endif
12001200

1201+
inline com_ptr<IStaticLifetimeCollection> get_static_lifetime_map()
1202+
{
1203+
auto const lifetime_factory = get_activation_factory<impl::IStaticLifetime>(L"Windows.ApplicationModel.Core.CoreApplication");
1204+
Windows::Foundation::IUnknown collection;
1205+
check_hresult(lifetime_factory->GetCollection(put_abi(collection)));
1206+
return collection.as<IStaticLifetimeCollection>();
1207+
}
1208+
12011209
template <typename D>
12021210
auto make_factory() -> typename impl::implements_default_interface<D>::type
12031211
{
@@ -1209,10 +1217,7 @@ namespace winrt::impl
12091217
}
12101218
else
12111219
{
1212-
auto const lifetime_factory = get_activation_factory<impl::IStaticLifetime>(L"Windows.ApplicationModel.Core.CoreApplication");
1213-
Windows::Foundation::IUnknown collection;
1214-
check_hresult(lifetime_factory->GetCollection(put_abi(collection)));
1215-
auto const map = collection.as<IStaticLifetimeCollection>();
1220+
auto const map = get_static_lifetime_map();
12161221
param::hstring const name{ name_of<typename D::instance_type>() };
12171222
void* result{};
12181223
map->Lookup(get_abi(name), &result);
@@ -1304,6 +1309,16 @@ WINRT_EXPORT namespace winrt
13041309
}
13051310
}
13061311

1312+
template <typename... FactoryClasses>
1313+
inline void clear_factory_static_lifetime()
1314+
{
1315+
auto unregister = [map = impl::get_static_lifetime_map()](param::hstring name)
1316+
{
1317+
map->Remove(get_abi(name));
1318+
};
1319+
((unregister(name_of<typename FactoryClasses::instance_type>())), ...);
1320+
}
1321+
13071322
template <typename D, typename... I>
13081323
struct implements : impl::producers<D, I...>, impl::base_implements<D, I...>::type
13091324
{

test/old_tests/Component/Events.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,51 @@ namespace winrt::Component::factory_implementation
7474

7575
bool Events::TestStaticLifetime()
7676
{
77+
auto GetReferenceCount = [this]()
78+
{
79+
AddRef();
80+
return Release();
81+
};
82+
7783
// Capture current reference count.
78-
AddRef();
79-
auto refcount = Release();
84+
auto refcount = GetReferenceCount();
8085

8186
// Reset constructor count.
8287
s_constructorCount = 0;
8388

84-
auto self = make_self<Events>();
85-
if (self.get() != this)
89+
// make_self should return a reference to ourselves
90+
// since we are static_lifetime.
91+
if (make_self<Events>().get() != this)
8692
{
8793
return false;
8894
}
89-
self = nullptr;
9095

9196
// Refcount should be unchanged.
97+
if (refcount != GetReferenceCount())
98+
{
99+
return false;
100+
}
101+
92102
// Should not have been constructed spuriously.
93-
AddRef();
94-
auto new_refcount = Release();
103+
if (s_constructorCount != 0)
104+
{
105+
return false;
106+
}
107+
108+
// Clear the static lifetime. That should drop the reference count.
109+
clear_factory_static_lifetime<Events>();
110+
if (refcount == GetReferenceCount())
111+
{
112+
return false;
113+
}
114+
115+
// Making a new object should put a different instance into
116+
// the static lifetime.
117+
if (make_self<Events>().get() == this)
118+
{
119+
return false;
120+
}
95121

96-
return refcount == new_refcount && s_constructorCount == 0;
122+
return true;
97123
}
98124
}

0 commit comments

Comments
 (0)