Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't wait for a connection to finish when a control is closed #5303

Merged
8 commits merged into from
Apr 9, 2020
31 changes: 26 additions & 5 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1969,6 +1969,26 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
_clipboardPasteHandlers(*this, *pasteArgs);
}

// Method Description:
// - Asynchronously close our connection. The Connection will likely wait
// until the attached process terminates before Close returns. If that's
// the case, we don't want to block the UI thread waiting on that process
// handle.
// Arguments:
// - <none>
// Return Value:
// - <none>
winrt::fire_and_forget TermControl::_AsyncCloseConnection()
{
if (auto localConnection{ std::exchange(_connection, nullptr) })
{
// Close the connection on the background thread.
co_await winrt::resume_background();
localConnection.Close();
// connection is destroyed.
}
}

void TermControl::Close()
{
if (!_closing.exchange(true))
Expand All @@ -1980,11 +2000,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
TSFInputControl().Close(); // Disconnect the TSF input control so it doesn't receive EditContext events.
_autoScrollTimer.Stop();

if (auto localConnection{ std::exchange(_connection, nullptr) })
{
localConnection.Close();
// connection is destroyed.
}
// GH#1996 - Close the connection asynchronously on a background
// thread.
// Since TermControl::Close is only ever triggered by the UI, we
// don't really care to wait for the connection to be completely
// closed. We can just do it whenever.
_AsyncCloseConnection();

if (auto localRenderEngine{ std::exchange(_renderEngine, nullptr) })
{
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
void _CurrentCursorPositionHandler(const IInspectable& sender, const CursorPositionEventArgs& eventArgs);
void _FontInfoHandler(const IInspectable& sender, const FontInfoEventArgs& eventArgs);

winrt::fire_and_forget _AsyncCloseConnection();

// this atomic is to be used as a guard against dispatching billions of coroutines for
// routine state changes that might happen millions of times a second.
// Unbounded main dispatcher use leads to massive memory leaks and intense slowdowns
Expand Down