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

Pump the message queue on frozen windows #16588

Merged
merged 6 commits into from
Jan 29, 2024

Conversation

lhecker
Copy link
Member

@lhecker lhecker commented Jan 22, 2024

This changeset ensures that the message queue of frozen windows is
always being serviced. This should ensure that it won't fill up and
lead to deadlocks, freezes, or similar. I've tried a lot of different
approaches before settling on this one. Introducing a custom WM_APP
message has the benefit of being the least intrusive to the existing
code base.

The approach that I would have favored the most would be to never
destroy the AppHost instance in the first place, as I imagined that
this would be more robust in general and resolve other (rare) bugs.
However, I found that this requires rewriting some substantial parts
of the code base around AppHost and it could be something that may
be of interest in the future.

Closes #16332
Depends on #16587 and #16575

@DHowett
Copy link
Member

DHowett commented Jan 22, 2024

Wait, I don't understand the difference between these two identically-named PRs

@lhecker lhecker changed the title Avoid timer ticks on frozen windows Pump the message queue on frozen windows Jan 22, 2024
@lhecker
Copy link
Member Author

lhecker commented Jan 22, 2024

I keep forgetting that GitHub doesn't fix the PR title when you change the base. 😑

{
return false;
}
if (msg.message == AppHost::WM_REFRIGERATE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw mike referred to the act of waking back up as Microwaving; refrigerating is when it goes down to sleep

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see - you have repurposed it to be a single flag. Transition between the states. etc

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I wasn't sure what to name it... "refrigerate" has the benefit that it only comes up in this context in the project, so it should be easier to find related code.

DHowett
DHowett previously approved these changes Jan 22, 2024
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would approve, but I'm a little curious on the ClearPersistedWindowState thing first

{
_windowLogic.ClearPersistedWindowState();
}

// Remove ourself from the list of peasants so that we aren't included in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very sus that this is just gone now - why? Is this related?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you expand the surrounding code in the diff viewer you'll notice that this block of code is a duplicate! I think it might have been an incorrect merge in the past.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh what the heck

src/cascadia/WindowsTerminal/WindowThread.cpp Show resolved Hide resolved
src/cascadia/WindowsTerminal/WindowThread.cpp Show resolved Hide resolved
@@ -26,6 +26,11 @@ NonClientIslandWindow::NonClientIslandWindow(const ElementTheme& requestedTheme)
{
}

NonClientIslandWindow::~NonClientIslandWindow()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added redundancy? I don't think we've got any code that was removed that was calling Close before, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it's terrible... This change fixes a bug and you might already know what I mean when I say: IslandWindow::Close is a virtual function which the ~IslandWindow destructor calls. NonClientIslandWindow overloads Close. boom

But in my opinion this sorely belongs into the "only obvious in hindsight" category of arcane C++ footnukes (can't have enough of those in a language!), so let me explain in more detail:

  • No matter whether you define a destructor or not, C++ will define it's own "real-destructor", because that one is responsible for destroying non-trival class members (like std::strings and such). So, while NonClientIslandWindow doesn't have an explicit destructor, it gets one anyways which virtually overloads the IslandWindow destructor.
  • With inheritance, destructors are called in reverse starting from child classes up to parent classes. In other words, first ~NonClientIslandWindow is called and then ~IslandWindow.

In short, when ~IslandWindow gets called and it tries to call the virtual function Close, the child class NonClientIslandWindow is already destroyed, which means that the vtable pointer now points to IslandWindow, which means that IslandWindow::Close is called and not NonClientIslandWindow::Close. The above change fixes this.

Co-authored-by: Mike Griese <migrie@microsoft.com>

This comment has been minimized.

Base automatically changed from dev/lhecker/16332-avoid-idle-timers to main January 23, 2024 17:00
@lhecker lhecker dismissed DHowett’s stale review January 23, 2024 17:00

The base branch was changed.

This comment has been minimized.

@microsoft-github-policy-service microsoft-github-policy-service bot added Issue-Bug It either shouldn't be doing this or needs an investigation. Area-Windowing Window frame, quake mode, tearout Product-Terminal The new Windows Terminal. labels Jan 23, 2024
@lhecker
Copy link
Member Author

lhecker commented Jan 23, 2024

FYI this PR sort of depends on #16575 because I had to (chose to?) remove ThrowAway. I think it will be fine even if ExitProcess is called, but I believe it'll be much safer with TerminateProcess so that the UI threads truly don't get a chance to destroy themselves.

{
_windowLogic.ClearPersistedWindowState();
}

// Remove ourself from the list of peasants so that we aren't included in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh what the heck

@lhecker lhecker added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jan 29, 2024
@DHowett DHowett merged commit 5d2fa47 into main Jan 29, 2024
20 checks passed
@DHowett DHowett deleted the dev/lhecker/16332-pump-frozen-queue branch January 29, 2024 22:01
DHowett pushed a commit that referenced this pull request Jan 29, 2024
This changeset ensures that the message queue of frozen windows is
always being serviced. This should ensure that it won't fill up and
lead to deadlocks, freezes, or similar. I've tried _a lot_ of different
approaches before settling on this one. Introducing a custom `WM_APP`
message has the benefit of being the least intrusive to the existing
code base.

The approach that I would have favored the most would be to never
destroy the `AppHost` instance in the first place, as I imagined that
this would be more robust in general and resolve other (rare) bugs.
However, I found that this requires rewriting some substantial parts
of the code base around `AppHost` and it could be something that may
be of interest in the future.

Closes #16332
Depends on #16587 and #16575

(cherry picked from commit 5d2fa47)
Service-Card-Id: 91642478
Service-Version: 1.18
DHowett pushed a commit that referenced this pull request Jan 29, 2024
This changeset ensures that the message queue of frozen windows is
always being serviced. This should ensure that it won't fill up and
lead to deadlocks, freezes, or similar. I've tried _a lot_ of different
approaches before settling on this one. Introducing a custom `WM_APP`
message has the benefit of being the least intrusive to the existing
code base.

The approach that I would have favored the most would be to never
destroy the `AppHost` instance in the first place, as I imagined that
this would be more robust in general and resolve other (rare) bugs.
However, I found that this requires rewriting some substantial parts
of the code base around `AppHost` and it could be something that may
be of interest in the future.

Closes #16332
Depends on #16587 and #16575

(cherry picked from commit 5d2fa47)
Service-Card-Id: 91642479
Service-Version: 1.19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Windowing Window frame, quake mode, tearout AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Terminal The new Windows Terminal.
Projects
Development

Successfully merging this pull request may close these issues.

Terminal window "not responding"
3 participants