Skip to content

Fix VS deadlock on shutdown.#6322

Merged
1 commit merged intomainfrom
nimullen/vsts.1529381
Apr 26, 2022
Merged

Fix VS deadlock on shutdown.#6322
1 commit merged intomainfrom
nimullen/vsts.1529381

Conversation

@NTaylorMullen
Copy link
Copy Markdown

@NTaylorMullen NTaylorMullen commented Apr 26, 2022

  • This is a contained fix to address a deadlock plagueing RPS tests on VS shutdown (it'd hang). See the associated issue for context.
  • This is a partial revert of cb46789

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1529381

- This is a contained fix to address a deadlock plagueing RPS tests on VS shutdown (it'd hang). See the associated issue for context.

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1529381
Copy link
Copy Markdown
Contributor

@allisonchou allisonchou left a comment

Choose a reason for hiding this comment

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

lgtm, although I still don't fully understand why the original deadlocks? (possibly need that threading overview meeting with @ryanbrandenburg we discussed before 😄)

@NTaylorMullen
Copy link
Copy Markdown
Author

NTaylorMullen commented Apr 26, 2022

lgtm, although I still don't fully understand why the original deadlocks? (possibly need that threading overview meeting with @ryanbrandenburg we discussed before 😄)

So the gist is that whenever we had a pattern like this:
image

Aka

ProjectManagerChanged {
    JTF.Run(() => { ... await switch to main thread...})
}

What effectively is happening is that our calling thread (the one calling ProjectManagerChanged) would then block synchronously until it was able to get back onto the main thread. That combined with our codebase doing ProjectSnapshotManagerDispatcher.RunOnDispatcherThread(() => {....}) in a context where the UI thread was also blocked would result in ProjectSnapshotManager.RunOnDispatcherThread never being able to get invoked because the other ProjectManagerChanged => JTF.Run was blocking it from running while simultaneously blocking the UI thread from being acquired.

Hopefully this clarifies a little but I absolutely still owe y'all a threading brown bag

@NTaylorMullen NTaylorMullen added the auto-merge Squash merge once all PR checks are complete and reviewers have approved label Apr 26, 2022
@ghost
Copy link
Copy Markdown

ghost commented Apr 26, 2022

Hello @NTaylorMullen!

Because this pull request has the auto-merge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 1ba9ea2 into main Apr 26, 2022
@ghost ghost deleted the nimullen/vsts.1529381 branch April 26, 2022 23:59
@allisonchou
Copy link
Copy Markdown
Contributor

That does help, thank you for the explanation!

@ryanbrandenburg
Copy link
Copy Markdown
Contributor

Thanks for catching my thread crimes Taylor! I could SWEAR I did all the instances of this, I don't know if I lost it in a rebase and didn't notice or what.

_joinableTaskContext.AssertUIThread();
await _documentManager.OnTextViewClosedAsync(textView, subjectBuffers);
});
_joinableTaskContext.AssertUIThread();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Asserting the current thread in an asynchronous method is an anti-pattern. This should either be a synchronous method that asserts its affinity, or an asynchronous method that switches on demand.


private void Document_ChangedOnDisk(object sender, EventArgs e)
{
_ = Document_ChangedOnDiskAsync((EditorDocument)sender, CancellationToken.None);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 This is an untracked fire-and-forget operation, which means tests will not be able to detect it or wait for it to complete.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge Squash merge once all PR checks are complete and reviewers have approved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants