more cleanup
This commit is contained in:
parent
354e4b00a3
commit
5c17603a94
|
@ -13,6 +13,69 @@ using namespace winrt::Windows::UI::Composition;
|
||||||
using namespace winrt::Windows::UI::Xaml::Hosting;
|
using namespace winrt::Windows::UI::Xaml::Hosting;
|
||||||
using namespace winrt::Windows::Foundation::Numerics;
|
using namespace winrt::Windows::Foundation::Numerics;
|
||||||
|
|
||||||
|
// We keep a weak ref to our ContentProcess singleton here.
|
||||||
|
// Why?
|
||||||
|
//
|
||||||
|
// We need to always return the _same_ ContentProcess when someone comes to
|
||||||
|
// instantiate this class. So we want to track the single instance we make. We
|
||||||
|
// also want to track when the last outstanding reference to this object is
|
||||||
|
// removed. If we're keeping a strong ref, then the ref count will always be > 1
|
||||||
|
|
||||||
|
winrt::weak_ref<winrt::Microsoft::Terminal::Control::ContentProcess> g_weak{ nullptr };
|
||||||
|
wil::unique_event g_canExitThread;
|
||||||
|
|
||||||
|
struct ContentProcessFactory : implements<ContentProcessFactory, IClassFactory>
|
||||||
|
{
|
||||||
|
ContentProcessFactory(winrt::guid g) :
|
||||||
|
_guid{ g } {};
|
||||||
|
|
||||||
|
HRESULT __stdcall CreateInstance(IUnknown* outer, GUID const& iid, void** result) noexcept final
|
||||||
|
{
|
||||||
|
*result = nullptr;
|
||||||
|
if (outer)
|
||||||
|
{
|
||||||
|
return CLASS_E_NOAGGREGATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_weak)
|
||||||
|
{
|
||||||
|
// Instantiate the ContentProcess here
|
||||||
|
winrt::Microsoft::Terminal::Control::ContentProcess strong{};
|
||||||
|
|
||||||
|
// Now, create a weak ref to that ContentProcess object.
|
||||||
|
winrt::weak_ref<winrt::Microsoft::Terminal::Control::ContentProcess> weak{ strong };
|
||||||
|
|
||||||
|
// Stash away that weak ref for future callers.
|
||||||
|
g_weak = weak;
|
||||||
|
return strong.as(iid, result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto strong = g_weak.get();
|
||||||
|
// !! LOAD BEARING !! If you set this event in the _first_ branch
|
||||||
|
// here, when we first create the object, then there will be _no_
|
||||||
|
// referernces to the ContentProcess object for a small slice. We'll
|
||||||
|
// stash the ContentProcess in the weak_ptr, and return it, and at
|
||||||
|
// that moment, there will be 0 outstanding references, it'll dtor,
|
||||||
|
// and wei'll ExitProcess.
|
||||||
|
//
|
||||||
|
// Instead, set the event here, once there's already a reference
|
||||||
|
// outside of just the weak one we keep. Experimentation showed this
|
||||||
|
// waw always hit when creating the ContentProcess at least once.
|
||||||
|
g_canExitThread.SetEvent();
|
||||||
|
return strong.as(iid, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT __stdcall LockServer(BOOL) noexcept final
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
winrt::guid _guid;
|
||||||
|
};
|
||||||
|
|
||||||
static bool checkIfContentProcess(winrt::guid& contentProcessGuid, HANDLE& eventHandle)
|
static bool checkIfContentProcess(winrt::guid& contentProcessGuid, HANDLE& eventHandle)
|
||||||
{
|
{
|
||||||
std::vector<std::wstring> args;
|
std::vector<std::wstring> args;
|
||||||
|
@ -52,63 +115,13 @@ static bool checkIfContentProcess(winrt::guid& contentProcessGuid, HANDLE& event
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::weak_ref<winrt::Microsoft::Terminal::Control::ContentProcess> g_weak{ nullptr };
|
|
||||||
wil::unique_event g_canExitThread;
|
|
||||||
|
|
||||||
struct HostClassFactory : implements<HostClassFactory, IClassFactory>
|
|
||||||
{
|
|
||||||
HostClassFactory(winrt::guid g) :
|
|
||||||
_guid{ g } {};
|
|
||||||
|
|
||||||
HRESULT __stdcall CreateInstance(IUnknown* outer, GUID const& iid, void** result) noexcept final
|
|
||||||
{
|
|
||||||
*result = nullptr;
|
|
||||||
if (outer)
|
|
||||||
{
|
|
||||||
return CLASS_E_NOAGGREGATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_weak)
|
|
||||||
{
|
|
||||||
winrt::Microsoft::Terminal::Control::ContentProcess strong{};
|
|
||||||
winrt::weak_ref<winrt::Microsoft::Terminal::Control::ContentProcess> weak{ strong };
|
|
||||||
g_weak = weak;
|
|
||||||
return strong.as(iid, result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto strong = g_weak.get();
|
|
||||||
// !! LOAD BEARING !! If you set this event in the _first_ branch
|
|
||||||
// here, when we first create the object, then there will be _no_
|
|
||||||
// referernces to the ContentProcess object for a small slice. We'll
|
|
||||||
// stash the ContentProcess in the weak_ptr, and return it, and at
|
|
||||||
// that moment, there will be 0 outstanding references, it'll dtor,
|
|
||||||
// and wei'll ExitProcess.
|
|
||||||
//
|
|
||||||
// Instead, set the event here, once there's already a reference
|
|
||||||
// outside of just the weak one we keep. Experimentation showed this
|
|
||||||
// waw always hit when creating the ContentProcess at least once.
|
|
||||||
g_canExitThread.SetEvent();
|
|
||||||
return strong.as(iid, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT __stdcall LockServer(BOOL) noexcept final
|
|
||||||
{
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
winrt::guid _guid;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void doContentProcessThing(const winrt::guid& contentProcessGuid, const HANDLE& eventHandle)
|
static void doContentProcessThing(const winrt::guid& contentProcessGuid, const HANDLE& eventHandle)
|
||||||
{
|
{
|
||||||
// !! LOAD BEARING !! - important to be a MTA for these COM calls.
|
// !! LOAD BEARING !! - important to be a MTA for these COM calls.
|
||||||
winrt::init_apartment();
|
winrt::init_apartment();
|
||||||
DWORD registrationHostClass{};
|
DWORD registrationHostClass{};
|
||||||
check_hresult(CoRegisterClassObject(contentProcessGuid,
|
check_hresult(CoRegisterClassObject(contentProcessGuid,
|
||||||
make<HostClassFactory>(contentProcessGuid).get(),
|
make<ContentProcessFactory>(contentProcessGuid).get(),
|
||||||
CLSCTX_LOCAL_SERVER,
|
CLSCTX_LOCAL_SERVER,
|
||||||
REGCLS_MULTIPLEUSE,
|
REGCLS_MULTIPLEUSE,
|
||||||
®istrationHostClass));
|
®istrationHostClass));
|
||||||
|
|
Loading…
Reference in a new issue