private static List <Tuple <XElement, XElement> > CreateNodeLabels(Dictionary <JoinableTask, XElement> tasksAndElements)
        {
            Requires.NotNull(tasksAndElements, nameof(tasksAndElements));

            var result = new List <Tuple <XElement, XElement> >();

            foreach (KeyValuePair <JoinableTask, XElement> tasksAndElement in tasksAndElements)
            {
                JoinableTask?pendingTask = tasksAndElement.Key;
                XElement?    node        = tasksAndElement.Value;
                int          queueIndex  = 0;
                foreach (JoinableTaskFactory.SingleExecuteProtector?pendingTasksElement in pendingTask.MainThreadQueueContents)
                {
                    queueIndex++;
                    XElement?callstackNode = Dgml.Node(node.Attribute("Id").Value + "MTQueue#" + queueIndex, GetAsyncReturnStack(pendingTasksElement));
                    XElement?callstackLink = Dgml.Link(callstackNode, node);
                    result.Add(Tuple.Create(callstackNode, callstackLink));
                }

                foreach (JoinableTaskFactory.SingleExecuteProtector?pendingTasksElement in pendingTask.ThreadPoolQueueContents)
                {
                    queueIndex++;
                    XElement?callstackNode = Dgml.Node(node.Attribute("Id").Value + "TPQueue#" + queueIndex, GetAsyncReturnStack(pendingTasksElement));
                    XElement?callstackLink = Dgml.Link(callstackNode, node);
                    result.Add(Tuple.Create(callstackNode, callstackLink));
                }
            }

            return(result);
        }
        private static ICollection <XElement> CreateCollectionContainingTaskLinks(Dictionary <JoinableTask, XElement> tasks, Dictionary <JoinableTaskCollection, XElement> collections)
        {
            Requires.NotNull(tasks, nameof(tasks));
            Requires.NotNull(collections, nameof(collections));

            var result = new List <XElement>();

            foreach (KeyValuePair <JoinableTask, XElement> task in tasks)
            {
                foreach (JoinableTaskCollection?collection in task.Key.ContainingCollections)
                {
                    XElement?collectionElement = collections[collection];
                    result.Add(Dgml.Link(collectionElement, task.Value).WithCategories("Contains"));
                }
            }

            return(result);
        }
        private static ICollection <XElement> CreatesLinksBetweenNodes(Dictionary <JoinableTask, XElement> pendingTasksElements)
        {
            Requires.NotNull(pendingTasksElements, nameof(pendingTasksElements));

            var links = new List <XElement>();

            foreach (KeyValuePair <JoinableTask, XElement> joinableTaskAndElement in pendingTasksElements)
            {
                foreach (JoinableTask?joinedTask in JoinableTaskDependencyGraph.GetAllDirectlyDependentJoinableTasks(joinableTaskAndElement.Key))
                {
                    if (pendingTasksElements.TryGetValue(joinedTask, out XElement? joinedTaskElement))
                    {
                        links.Add(Dgml.Link(joinableTaskAndElement.Value, joinedTaskElement));
                    }
                }
            }

            return(links);
        }
Exemplo n.º 4
0
        private static ICollection <XElement> CreatesLinksBetweenNodes(Dictionary <JoinableTask, XElement> pendingTasksElements)
        {
            Requires.NotNull(pendingTasksElements, nameof(pendingTasksElements));

            var links = new List <XElement>();

            foreach (var joinableTaskAndElement in pendingTasksElements)
            {
                foreach (var joinedTask in joinableTaskAndElement.Key.ChildOrJoinedJobs)
                {
                    if (pendingTasksElements.TryGetValue(joinedTask, out XElement joinedTaskElement))
                    {
                        links.Add(Dgml.Link(joinableTaskAndElement.Value, joinedTaskElement));
                    }
                }
            }

            return(links);
        }
Exemplo n.º 5
0
        protected virtual HangReportContribution GetHangReport()
        {
            using (this.NoMessagePumpSynchronizationContext.Apply())
            {
                // It's possible that the hang is due to a deadlock on our own private lock,
                // so while we're reporting the hang, don't accidentally deadlock ourselves
                // while trying to do the right thing by taking the lock.
                bool lockAcquired = false;
                try
                {
                    Monitor.TryEnter(this.syncObject, 1000, ref lockAcquired);
                    var dgml = CreateDgml(out XElement nodes, out XElement links);

                    if (!lockAcquired)
                    {
                        nodes.Add(Dgml.Comment("WARNING: failed to acquire our own lock in formulating this report."));
                    }

                    var liveAwaiterMetadata = new HashSet <AwaiterMetadata>();
                    liveAwaiterMetadata.UnionWith(this.waitingReaders.Select(a => new AwaiterMetadata(a, AwaiterCollection.Waiting | AwaiterCollection.ReadLock)));
                    liveAwaiterMetadata.UnionWith(this.waitingUpgradeableReaders.Select(a => new AwaiterMetadata(a, AwaiterCollection.Waiting | AwaiterCollection.UpgradeableReadLock)));
                    liveAwaiterMetadata.UnionWith(this.waitingWriters.Select(a => new AwaiterMetadata(a, AwaiterCollection.Waiting | AwaiterCollection.WriteLock)));
                    liveAwaiterMetadata.UnionWith(this.issuedReadLocks.Select(a => new AwaiterMetadata(a, AwaiterCollection.Issued | AwaiterCollection.ReadLock)));
                    liveAwaiterMetadata.UnionWith(this.issuedUpgradeableReadLocks.Select(a => new AwaiterMetadata(a, AwaiterCollection.Issued | AwaiterCollection.UpgradeableReadLock)));
                    liveAwaiterMetadata.UnionWith(this.issuedWriteLocks.Select(a => new AwaiterMetadata(a, AwaiterCollection.Issued | AwaiterCollection.WriteLock)));

                    var liveAwaiters            = liveAwaiterMetadata.Select(am => am.Awaiter);
                    var releasedAwaiterMetadata = new HashSet <AwaiterMetadata>(liveAwaiters.SelectMany(GetLockStack).Distinct().Except(liveAwaiters).Select(AwaiterMetadata.Released));
                    var allAwaiterMetadata      = new HashSet <AwaiterMetadata>(liveAwaiterMetadata.Concat(releasedAwaiterMetadata));

                    // Build the lock stack containers.
                    dgml.WithContainers(allAwaiterMetadata.Select(am => am.GroupId).Distinct().Select(id => Dgml.Container(id, "Lock stack")));

                    // Add each lock awaiter.
                    nodes.Add(allAwaiterMetadata.Select(am => CreateAwaiterNode(am.Awaiter).WithCategories(am.Categories.ToArray()).ContainedBy(am.GroupId, dgml)));

                    // Link the lock stacks among themselves.
                    links.Add(allAwaiterMetadata.Where(a => a.Awaiter.NestingLock != null).Select(a => Dgml.Link(GetAwaiterId(a.Awaiter.NestingLock), GetAwaiterId(a.Awaiter))));

                    return(new HangReportContribution(
                               dgml.ToString(),
                               "application/xml",
                               this.GetType().Name + ".dgml"));
                }
                finally
                {
                    if (lockAcquired)
                    {
                        Monitor.Exit(this.syncObject);
                    }
                }
            }
        }