This seems to work to create a thread listening for the monarch, and safely tear it down. It _seems_ like it.
This commit is contained in:
parent
e101efd11d
commit
e1402d834f
|
@ -15,6 +15,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
{
|
||||
WindowManager::WindowManager()
|
||||
{
|
||||
_monarchWaitInterrupt.create();
|
||||
|
||||
// Register with COM as a server for the Monarch class
|
||||
_registerAsMonarch();
|
||||
// Instantiate an instance of the Monarch. This may or may not be in-proc!
|
||||
|
@ -29,6 +31,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
// monarch!
|
||||
CoRevokeClassObject(_registrationHostClass);
|
||||
_registrationHostClass = 0;
|
||||
_monarchWaitInterrupt.SetEvent();
|
||||
if (_electionThread.joinable())
|
||||
{
|
||||
_electionThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
void WindowManager::ProposeCommandline(const Remoting::CommandlineArgs& args)
|
||||
|
@ -47,6 +54,12 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
// instance, and tell that peasant to handle that commandline.
|
||||
_createOurPeasant();
|
||||
|
||||
// TODO:MG Spawn a thread to wait on the monarch, and handle the election
|
||||
if (!isKing)
|
||||
{
|
||||
_createPeasantThread();
|
||||
}
|
||||
|
||||
_peasant.ExecuteCommandline(args);
|
||||
}
|
||||
// Otherwise, we'll do _nothing_.
|
||||
|
@ -93,11 +106,75 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
_peasant = *p;
|
||||
_monarch.AddPeasant(_peasant);
|
||||
|
||||
// TODO:MG Spawn a thread to wait on the monarch, and handle the election
|
||||
|
||||
return _peasant;
|
||||
}
|
||||
|
||||
bool WindowManager::_electionNight2020()
|
||||
{
|
||||
_createMonarch();
|
||||
if (_areWeTheKing())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WindowManager::_createPeasantThread()
|
||||
{
|
||||
// If we catch an exception trying to get at the monarch ever, we can
|
||||
// set the _monarchWaitInterrupt, and use that to trigger a new
|
||||
// election. Though, we wouldn't be able to retry the function that
|
||||
// caused the exception in the first place...
|
||||
|
||||
_electionThread = std::thread([this] {
|
||||
HANDLE waits[2];
|
||||
waits[1] = _monarchWaitInterrupt.get();
|
||||
|
||||
bool exitRequested = false;
|
||||
while (!exitRequested)
|
||||
{
|
||||
wil::unique_handle hMonarch{ OpenProcess(PROCESS_ALL_ACCESS, FALSE, static_cast<DWORD>(_monarch.GetPID())) };
|
||||
// TODO:MG
|
||||
// if (hMonarch.get() == nullptr)
|
||||
// {
|
||||
// const auto gle = GetLastError();
|
||||
// return false;
|
||||
// }
|
||||
waits[0] = hMonarch.get();
|
||||
auto waitResult = WaitForMultipleObjects(2, waits, FALSE, INFINITE);
|
||||
|
||||
switch (waitResult)
|
||||
{
|
||||
case WAIT_OBJECT_0 + 0: // waits[0] was signaled
|
||||
// printf("THE KING IS \x1b[31mDEAD\x1b[m\n");
|
||||
// // Return false here - this will trigger us to find the new monarch
|
||||
// return false;
|
||||
//
|
||||
// TODO:MG Connect to the new monarch, which might be us!
|
||||
exitRequested = _electionNight2020();
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1: // waits[1] was signaled
|
||||
exitRequested = true;
|
||||
break;
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
printf("Wait timed out. This should be impossible.\n");
|
||||
exitRequested = true;
|
||||
break;
|
||||
|
||||
// Return value is invalid.
|
||||
default:
|
||||
{
|
||||
auto gle = GetLastError();
|
||||
printf("WaitForMultipleObjects returned: %d\n", waitResult);
|
||||
printf("Wait error: %d\n", gle);
|
||||
ExitProcess(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Remoting::Peasant WindowManager::CurrentWindow()
|
||||
{
|
||||
return _peasant;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace winrt::Microsoft::Terminal::Remoting::implementation
|
||||
{
|
||||
struct WindowManager final : public WindowManagerT<WindowManager>
|
||||
struct WindowManager final : public WindowManagerT<WindowManager>
|
||||
{
|
||||
WindowManager();
|
||||
~WindowManager();
|
||||
|
@ -23,10 +23,16 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
|
|||
winrt::Microsoft::Terminal::Remoting::Monarch _monarch{ nullptr };
|
||||
winrt::Microsoft::Terminal::Remoting::Peasant _peasant{ nullptr };
|
||||
|
||||
wil::unique_event _monarchWaitInterrupt;
|
||||
std::thread _electionThread;
|
||||
|
||||
void _registerAsMonarch();
|
||||
void _createMonarch();
|
||||
bool _areWeTheKing();
|
||||
winrt::Microsoft::Terminal::Remoting::IPeasant _createOurPeasant();
|
||||
|
||||
bool _electionNight2020();
|
||||
void _createPeasantThread();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue