private static void RemoveDependingSynchronousTask()

in src/Microsoft.VisualStudio.Threading/JoinableTaskDependencyGraph.cs [948:1021]


            private static void RemoveDependingSynchronousTask(IJoinableTaskDependent taskOrCollection, JoinableTask task, HashSet<IJoinableTaskDependent>? reachableNodesReadOnlySet, ref HashSet<IJoinableTaskDependent>? remainingDependentNodes)
            {
                Requires.NotNull(taskOrCollection, nameof(taskOrCollection));
                Requires.NotNull(task, nameof(task));

                ref JoinableTaskDependentData data = ref taskOrCollection.GetJoinableTaskDependentData();
                DependentSynchronousTask? previousTaskTracking = null;
                DependentSynchronousTask? currentTaskTracking = data.dependingSynchronousTaskTracking;
                bool removed = false;

                while (currentTaskTracking is object)
                {
                    if (currentTaskTracking.SynchronousTask == task)
                    {
                        if (--currentTaskTracking.ReferenceCount > 0)
                        {
                            if (reachableNodesReadOnlySet is object)
                            {
                                if (!reachableNodesReadOnlySet.Contains(taskOrCollection))
                                {
                                    currentTaskTracking.ReferenceCount = 0;
                                }
                            }
                        }

                        if (currentTaskTracking.ReferenceCount == 0)
                        {
                            removed = true;
                            if (previousTaskTracking is object)
                            {
                                previousTaskTracking.Next = currentTaskTracking.Next;
                            }
                            else
                            {
                                data.dependingSynchronousTaskTracking = currentTaskTracking.Next;
                            }
                        }

                        if (reachableNodesReadOnlySet is null)
                        {
                            // if a node doesn't have dependencies, it cannot be a part of a dependency circle.
                            if (removed || taskOrCollection.GetJoinableTaskDependentData().HasNoChildDependentNode)
                            {
                                if (remainingDependentNodes is object)
                                {
                                    remainingDependentNodes.Remove(taskOrCollection);
                                }
                            }
                            else
                            {
                                if (remainingDependentNodes is null)
                                {
                                    remainingDependentNodes = new HashSet<IJoinableTaskDependent>();
                                }

                                remainingDependentNodes.Add(taskOrCollection);
                            }
                        }

                        break;
                    }

                    previousTaskTracking = currentTaskTracking;
                    currentTaskTracking = currentTaskTracking.Next;
                }

                if (removed && data.childDependentNodes is object)
                {
                    foreach (KeyValuePair<IJoinableTaskDependent, int> item in data.childDependentNodes)
                    {
                        RemoveDependingSynchronousTask(item.Key, task, reachableNodesReadOnlySet, ref remainingDependentNodes);
                    }
                }
            }