microsoft / microsoft/vs-threading

CPS lock aware JTF doesn't work correctly, when RaiseTransitioningEvents is not fired

Open
#228 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C#
Stars
1k
Forks
160
Avg merge
1d 12h
Merged PRs (30d)
28

Description

We noticed some JoinableTask/Project lock hangs due to the JTF holding a lock (and switching to UI thread) is not added to the lock service collection, even those JTFs are created with the lock aware JTF factory.

It is caused by a special optimization logic in JTF library.
https://github.com/Microsoft/vs-threading/blob/022a5269613e7093c2ffb6c7a1074b8d416e268b/src/Microsoft.VisualStudio.Threading/JoinableTask.cs#L572-L575

The condition here to skip the event when synchronouslyBlockingMainThread is true is not correct. The current JTF is UI thread blocking task doesn't ensure that SwitchToUIThread won't be blocked due to several reasons:

  1. the UI thread can run into a child JTF.Run on the top of the earlier task. The inner JTF.Run will not allow the task related to the outside JTF.Run to go to the UI thread by default.

  2. the UI thread blocking JTF may have completed. It is very common a spin off task (either Task.Run, or Dataflow.Post can easily leak JTF, or it can be captured by many places capturing ExecutionContext, like a task continuation point, or cancellationToken registration) can retain the old JTF, which may have been completed. A completed UI thread blocking JTF doesn't provide any advantage for the later request to switch to the UI thread.

In both cases, the pending JTF will not be tracked by the lock service due to this issue, and leads product to run into a dead lock.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in JoinableTask.cs at the linked optimization around lines 572-575, then trace how RaiseTransitioningEvents and the lock service collection handle UI-thread-blocking tasks. Reproduce or add coverage for nested JTF.Run and completed UI-thread-blocking JTF cases; done means pending JTFs remain tracked so these scenarios do not cause a deadlock.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.