Skip to content

Commit 294add8

Browse files
author
Lifeng Lu
committed
Fix inconsistent JTF dependency logic in the code.
The refcount skips completed tasks, but dependency walk through them. It will lead the dependency graph computation to go wrong, and leave stale dependencies to finished tasks when there is a cicular dependency loop. Ths problem is exposed through a new unit test.
1 parent 33ada20 commit 294add8

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/Microsoft.VisualStudio.Threading/JoinableTask.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,9 @@ internal void CompleteOnCurrentThread()
940940
}
941941
else if (tryAgainAfter is object)
942942
{
943+
// prevent referencing tasks which may be GCed during the waiting cycle.
944+
visited?.Clear();
945+
943946
ThreadingEventSource.Instance.WaitSynchronouslyStart();
944947
this.owner.WaitSynchronously(tryAgainAfter);
945948
ThreadingEventSource.Instance.WaitSynchronouslyStop();
@@ -1070,7 +1073,7 @@ private static bool TryDequeueSelfOrDependencies(IJoinableTaskDependent currentN
10701073

10711074
if (work is null)
10721075
{
1073-
if (joinableTask?.IsFullyCompleted != true)
1076+
if (joinableTask?.IsCompleteRequested != true)
10741077
{
10751078
foreach (IJoinableTaskDependent? item in JoinableTaskDependencyGraph.GetDirectDependentNodes(currentNode))
10761079
{

src/Microsoft.VisualStudio.Threading/JoinableTaskDependencyGraph.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ internal static void AddSelfAndDescendentOrJoinedJobs(IJoinableTaskDependent tas
453453

454454
if (taskOrCollection is JoinableTask thisJoinableTask)
455455
{
456-
if (thisJoinableTask.IsFullyCompleted || !joinables.Add(thisJoinableTask))
456+
if (thisJoinableTask.IsFullyCompleted || !joinables.Add(thisJoinableTask) || thisJoinableTask.IsCompleteRequested)
457457
{
458458
return;
459459
}
@@ -535,6 +535,11 @@ internal static void ComputeSelfAndDescendentOrJoinedJobsAndRemainTasks(IJoinabl
535535
return;
536536
}
537537

538+
if ((taskOrCollection as JoinableTask)?.IsCompleteRequested == true)
539+
{
540+
return;
541+
}
542+
538543
WeakKeyDictionary<IJoinableTaskDependent, int>? dependencies = taskOrCollection.GetJoinableTaskDependentData().childDependentNodes;
539544
if (dependencies is object)
540545
{

0 commit comments

Comments
 (0)