示例#1
0
        /// <summary>
        /// This function checks if the given ProjectBuildState is caused by a given parent target (via
        /// a dependency, onerror or IBuildEngine relationship)
        /// </summary>
        internal bool CheckBuildContextForParentMatch
        (
            EngineCallback engineCallback,
            TargetIdWrapper parentId,
            Target target,
            ProjectBuildState projectBuildState
        )
        {
            BuildRequest parentRequest = null;

            TargetInProgessState.TargetIdWrapper parentName =
                FindParentTarget(engineCallback, projectBuildState, target, out parentRequest);

            if (parentName != null && parentName.Equals(parentId))
            {
                return(true);
            }

            if (parentRequest != null)
            {
                for (int j = 0; j < parentBuildRequests.Count; j++)
                {
                    if (parentRequest.HandleId == parentBuildRequests[j].HandleId &&
                        parentRequest.RequestId == parentBuildRequests[j].RequestId)
                    {
                        if (parentTargetsForBuildRequests[j].Equals(parentId))
                        {
                            return(true);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }
            }
            return(false);
        }
示例#2
0
        /// <summary>
        /// For each target that has a cross node build request waiting for it to complete, iterate
        /// over the list of outstanding requests and find the matching out going request. Once
        /// the matching request is found - link the parent and child targets.
        /// </summary>
        private void LinkCrossNodeBuildRequests()
        {
            foreach (GraphNode node in dependencyGraph.Values)
            {
                TargetInProgessState.TargetIdWrapper[] parentsForBuildRequests =
                    new TargetInProgessState.TargetIdWrapper[node.targetState.ParentBuildRequests.Count];

                for (int j = 0; j < node.targetState.ParentBuildRequests.Count; j++)
                {
                    BuildRequest buildRequest = node.targetState.ParentBuildRequests[j];
                    int          nodeIndex    = buildRequest.NodeIndex;
                    int          handleId     = buildRequest.HandleId;
                    int          requestId    = buildRequest.RequestId;
                    bool         foundParent  = false;

                    // Skip requests that originated from the host
                    if (handleId == EngineCallback.invalidEngineHandle)
                    {
                        node.isRoot = true;
                        continue;
                    }

                    // If the request being analyzed came from one of the child nodes, its incoming external request's
                    // handleId will point at a routing context on the parent engine. If the outgoing request
                    // orginated from another child the two requests (outgoing and incoming) point at different
                    // routing contexts. In that case it is necessary to unwind the incoming request to the routing
                    // context of the outgoing request. If outgoing request originated from the parent node -
                    // there will be only one routing request.
                    if (node.targetState.TargetId.nodeId != 0)
                    {
                        ExecutionContext      executionContext = engineCallback.GetExecutionContextFromHandleId(buildRequest.HandleId);
                        RequestRoutingContext routingContext   = executionContext as RequestRoutingContext;
                        if (routingContext != null && routingContext.ParentHandleId != EngineCallback.invalidEngineHandle)
                        {
                            ExecutionContext nextExecutionContext = engineCallback.GetExecutionContextFromHandleId(routingContext.ParentHandleId);

                            if (nextExecutionContext is RequestRoutingContext)
                            {
                                nodeIndex = nextExecutionContext.NodeIndex;
                                handleId  = routingContext.ParentHandleId;
                                requestId = routingContext.ParentRequestId;
                            }
                        }
                        else
                        {
                            // Skip requests that originated from the host
                            node.isRoot = true;
                            continue;
                        }
                    }

                    // Iterate over all outstanding requests until a match is found
                    foreach (DictionaryEntry entry in outstandingExternalRequests)
                    {
                        BuildRequest[] externalRequests = (BuildRequest[])entry.Value;
                        for (int i = 0; i < externalRequests.Length && !foundParent; i++)
                        {
                            if (handleId == externalRequests[i].HandleId &&
                                requestId == externalRequests[i].RequestId &&
                                nodeIndex == externalRequests[i].NodeIndex)
                            {
                                // Verify that the project name is the same
                                ErrorUtilities.VerifyThrow(
                                    String.Compare(buildRequest.ProjectFileName, externalRequests[i].ProjectFileName, StringComparison.OrdinalIgnoreCase) == 0,
                                    "The two requests should have the same project name");

                                // Link the two graph nodes together
                                GraphNode parentNode = (GraphNode)dependencyGraph[entry.Key];
                                parentNode.children.Add(node);

                                parentsForBuildRequests[j] = parentNode.targetState.TargetId;

                                foundParent = true;
                            }
                        }

                        if (foundParent)
                        {
                            break;
                        }
                    }
                }
                node.targetState.ParentTargetsForBuildRequests = parentsForBuildRequests;
            }
        }