Skip to content

Commit

Permalink
last commit before the holidays
Browse files Browse the repository at this point in the history
  • Loading branch information
zadjii-msft committed Dec 18, 2020
1 parent 5939636 commit c088895
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 80 deletions.
9 changes: 1 addition & 8 deletions src/cascadia/Remoting/Monarch.cpp
Expand Up @@ -63,13 +63,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// Add an event listener to the peasant's WindowActivated event.
peasant.WindowActivated({ this, &Monarch::_peasantWindowActivated });

// TODO:projects/5 Wait on the peasant's PID, and remove them from the
// map if they die. This won't work great in tests though, with fake
// PIDs.
//
// We should trigger a callback. The manager will use this callback as
// an opportunity to start waiting on the new peasant.

return newPeasantsId;
}

Expand Down Expand Up @@ -115,7 +108,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
catch (...)
{
LOG_CAUGHT_EXCEPTION();
// TODO: Remove the peasant from the list of peasants
// Remove the peasant from the list of peasants
_peasants.erase(peasantID);
return nullptr;
}
Expand Down
124 changes: 58 additions & 66 deletions src/cascadia/Remoting/WindowManager.cpp
Expand Up @@ -16,11 +16,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
WindowManager::WindowManager()
{
_monarchWaitInterrupt.create();
// _peasantListenerInterrupt.create();

// wil::unique_event peasantListenerInterrupt;
// peasantListenerInterrupt.create();
// _peasantHandles.emplace_back(std::move(peasantListenerInterrupt));

// Register with COM as a server for the Monarch class
_registerAsMonarch();
Expand All @@ -37,15 +32,11 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
CoRevokeClassObject(_registrationHostClass);
_registrationHostClass = 0;
_monarchWaitInterrupt.SetEvent();
// _peasantListenerInterrupt.SetEvent();

if (_electionThread.joinable())
{
_electionThread.join();
}
// if (_peasantListenerThread.joinable())
// {
// _peasantListenerThread.join();
// }
}

void WindowManager::ProposeCommandline(const Remoting::CommandlineArgs& args)
Expand Down Expand Up @@ -113,20 +104,6 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
}
// Here, we're the king!

// TODO:MG Add an even handler to the monarch's PeasantAdded event.
// We'll use that callback as a chance to start waiting on the peasant's
// PID. If they die, we'll tell the monarch to remove them from the
// list.
// _peasantHandles.emplace_back(_peasantListenerInterrupt.get());

// _peasantListenerThread = std::thread([this]() {

// bool exitRequested = false;
// while (!exitRequested)
// {
// }
// });

// Wait, don't. Let's just have the monarch try/catch any accesses to
// peasants. If the peasant dies, then it can't get the peasant's
// anything. In that case, _remove it_.
Expand All @@ -151,6 +128,10 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
bool WindowManager::_electionNight2020()
{
_createMonarchAndCallbacks();

// Tell the new monarch who we are. We might be that monarch!
_monarch.AddPeasant(_peasant);

if (_areWeTheKing())
{
return true;
Expand All @@ -166,51 +147,62 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
// caused the exception in the first place...

_electionThread = std::thread([this] {
HANDLE waits[2];
waits[1] = _monarchWaitInterrupt.get();
_waitOnMonarchThread();
});
}

void WindowManager::_waitOnMonarchThread()
{
HANDLE waits[2];
waits[1] = _monarchWaitInterrupt.get();

bool exitRequested = false;
while (!exitRequested)
bool exitRequested = false;
while (!exitRequested)
{
wil::unique_handle hMonarch{ OpenProcess(PROCESS_ALL_ACCESS,
FALSE,
static_cast<DWORD>(_monarch.GetPID())) };
// TODO:MG If we fail to open the monarch, then they don't exist
// anymore! Go straight to an election.
//
// TODO:MG At any point in all this, the current monarch might die.
// We go straight to a new election, right? Worst case, eventually,
// we'll become the new monarch.
//
// if (hMonarch.get() == nullptr)
// {
// const auto gle = GetLastError();
// return false;
// }
waits[0] = hMonarch.get();
auto waitResult = WaitForMultipleObjects(2, waits, FALSE, INFINITE);

switch (waitResult)
{
wil::unique_handle hMonarch{ OpenProcess(PROCESS_ALL_ACCESS, FALSE, static_cast<DWORD>(_monarch.GetPID())) };
// TODO:MG If we fail to open the monarch, then they don't exist
// anymore! Go straight to an election.
//
// 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
// Connect to the new monarch, which might be us!
// If we become the monarch, then we'll return true and exit this thread.
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);
}
}
case WAIT_OBJECT_0 + 0: // waits[0] was signaled
// Connect to the new monarch, which might be us!
// If we become the monarch, then we'll return true and exit this thread.
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()
Expand Down
6 changes: 1 addition & 5 deletions src/cascadia/Remoting/WindowManager.h
Expand Up @@ -24,13 +24,8 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation
winrt::Microsoft::Terminal::Remoting::Peasant _peasant{ nullptr };

wil::unique_event _monarchWaitInterrupt;
// wil::unique_event _peasantListenerInterrupt;

std::thread _electionThread;
// std::thread _peasantListenerThread;

// // NON-OWNING HANDLES
// std::vector<HANDLE> _peasantHandles{};

void _registerAsMonarch();
void _createMonarch();
Expand All @@ -40,6 +35,7 @@ namespace winrt::Microsoft::Terminal::Remoting::implementation

bool _electionNight2020();
void _createPeasantThread();
void _waitOnMonarchThread();
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/UnitTests_Remoting/RemotingTests.cpp
Expand Up @@ -279,14 +279,14 @@ namespace RemotingUnitTests

VERIFY_ARE_EQUAL(2u, m0->_peasants.size());

Log::Comment(L"Kill peasant 1. Make sure that it gets removed from the monarch.");
RemotingTests::_killPeasant(m0, p1->GetID());

auto maybeP2 = m0->_getPeasant(2);
VERIFY_IS_NOT_NULL(maybeP2);
VERIFY_ARE_EQUAL(peasant2PID, maybeP2.GetPID());

auto maybeP1 = m0->_getPeasant(1);
// VERIFY_ARE_EQUAL(peasant1PID, maybeP1.GetPID());
VERIFY_IS_NULL(maybeP1);

VERIFY_ARE_EQUAL(1u, m0->_peasants.size());
Expand Down

1 comment on commit c088895

@github-actions

This comment was marked as outdated.

Please sign in to comment.