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

config/output: reconfigure on commit failure #5521

Closed
wants to merge 1 commit into from

Conversation

RedSoxFan
Copy link
Member

@RedSoxFan RedSoxFan commented Jul 6, 2020

Fixes #5483

Note that this only addresses the crash. I opened #5522 to provide a
way to destroy the headless output.

If the wlr_output_commit fails and the output was previously enabled, we
re-enable the output. If the output was previously enabled, then it was
also configured. Without reenabling or reconfiguring the output, the
output is left in an invalid state. This adds the missing reconfiguring
step.

This also adds safe guards in output_disable to prevent removing an
output index that is not in the list.

If the wlr_output_commit fails and the output was previously enabled, we
re-enable the output. If the output was previously enabled, then it was
also configured. Without reenabling or reconfiguring the output, the
output is left in an invalid state. This adds the missing reconfiguring
step.

This also adds safe guards in output_disable to prevent removing an
output index that is not in the list.
@emersion
Copy link
Member

emersion commented Jul 6, 2020

Hmm, this is getting a little bit complicated. I'm not a huge fan of this approach because we need to save/restore more output properties than before. This logic would be nicer if we only marked an output as enabled once the commit was successful. What was the reason why we don't do this? Because of output.events.mode/commit/etc events maybe?

@RedSoxFan
Copy link
Member Author

Hmm, this is getting a little bit complicated. I'm not a huge fan of this approach because we need to save/restore more output properties than before.

Yeah. Unfortunately.

This logic would be nicer if we only marked an output as enabled once the commit was successful. What was the reason why we don't do this? Because of output.events.mode/commit/etc events maybe?

The case where an output is disabled and the commit fails for enabling it is easy. We just flip the enabled boolean back, which does need to be enabled for the output event handlers.

The issue and complication is actually the other way - the output was enabled and the commit to disable it fails. This case should be much more rare, but still should be handled. If we don't re-enable and reconfigure the output, then we are left in a state where wlroots thinks the output is enabled, but sway doesn't. This leads to the output being frozen on the last frame or just the default swaybg gray, which can cascade to more problems due to the invalid state if the output gets disconnected or the user issues an enable for the output.

bool was_enabled = output->enabled;
bool was_configured = output->configured;
double old_x = 0, old_y = 0;

if (oc && !oc->enabled) {
// Output is configured to be disabled
sway_log(SWAY_DEBUG, "Disabling output %s", oc->name);
if (output->enabled) {
output_disable(output);
Copy link
Member

Choose a reason for hiding this comment

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

What about only calling output_disable once the output commit succeeds?

@emersion
Copy link
Member

emersion commented Jul 8, 2020

The issue and complication is actually the other way - the output was enabled and the commit to disable it fails. This case should be much more rare, but still should be handled. If we don't re-enable and reconfigure the output, then we are left in a state where wlroots thinks the output is enabled, but sway doesn't. This leads to the output being frozen on the last frame or just the default swaybg gray, which can cascade to more problems due to the invalid state if the output gets disconnected or the user issues an enable for the output.

Sure. I was mainly asking why we need to flip the enabled flag before the output commit. If we can flip it after, then no need for complicated rollback logic.

It turns out we have a handle_mode listener which needs this flag to know whether the backend turned the output on on its own or not. Ref swaywm/wlroots#2300 and swaywm/wlroots#2094.

emersion added a commit to emersion/sway that referenced this pull request Jul 10, 2020
Previously, we called output_disable prior to wlr_output_commit. This
mutates Sway's output state before the output commit actually succeeds.
This results in Sway's state getting out-of-sync with wlroots'.

An alternative fix [1] was to revert the changes made by output_disable
in case of failure. This is a little complicated. Instead, this patch
makes it so Sway's internal state is never changed before a successful
wlr_output commit.

We had two output flags: enabled and configured. However enabled was set
prior to the output becoming enabled, and was used to prevent the output
event handlers (specifically, the mode handler) from calling
apply_output_config again (infinite loop).

Rename enabled to enabling and use it exclusively for this purpose.
Rename configure to enabled, because that's what it really means.

[1]: swaywm#5521

Closes: swaywm#5483
RedSoxFan pushed a commit that referenced this pull request Jul 10, 2020
Previously, we called output_disable prior to wlr_output_commit. This
mutates Sway's output state before the output commit actually succeeds.
This results in Sway's state getting out-of-sync with wlroots'.

An alternative fix [1] was to revert the changes made by output_disable
in case of failure. This is a little complicated. Instead, this patch
makes it so Sway's internal state is never changed before a successful
wlr_output commit.

We had two output flags: enabled and configured. However enabled was set
prior to the output becoming enabled, and was used to prevent the output
event handlers (specifically, the mode handler) from calling
apply_output_config again (infinite loop).

Rename enabled to enabling and use it exclusively for this purpose.
Rename configure to enabled, because that's what it really means.

[1]: #5521

Closes: #5483
emersion added a commit to emersion/sway that referenced this pull request Jul 15, 2020
Previously, we called output_disable prior to wlr_output_commit. This
mutates Sway's output state before the output commit actually succeeds.
This results in Sway's state getting out-of-sync with wlroots'.

An alternative fix [1] was to revert the changes made by output_disable
in case of failure. This is a little complicated. Instead, this patch
makes it so Sway's internal state is never changed before a successful
wlr_output commit.

We had two output flags: enabled and configured. However enabled was set
prior to the output becoming enabled, and was used to prevent the output
event handlers (specifically, the mode handler) from calling
apply_output_config again (infinite loop).

Rename enabled to enabling and use it exclusively for this purpose.
Rename configure to enabled, because that's what it really means.

[1]: swaywm#5521

Closes: swaywm#5483
(cherry picked from commit 5432f00)
Geo25rey pushed a commit to Geo25rey/sway that referenced this pull request Aug 16, 2020
Previously, we called output_disable prior to wlr_output_commit. This
mutates Sway's output state before the output commit actually succeeds.
This results in Sway's state getting out-of-sync with wlroots'.

An alternative fix [1] was to revert the changes made by output_disable
in case of failure. This is a little complicated. Instead, this patch
makes it so Sway's internal state is never changed before a successful
wlr_output commit.

We had two output flags: enabled and configured. However enabled was set
prior to the output becoming enabled, and was used to prevent the output
event handlers (specifically, the mode handler) from calling
apply_output_config again (infinite loop).

Rename enabled to enabling and use it exclusively for this purpose.
Rename configure to enabled, because that's what it really means.

[1]: swaywm#5521

Closes: swaywm#5483
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1.5-rc1: Segfault in ipc_json_describe_workspace
2 participants