Пример #1
0
        internal TargetInProgessState
        (
            EngineCallback engineCallback,
            Target target,
            List <ProjectBuildState> waitingBuildStates,
            ProjectBuildState initiatingRequest,
            BuildRequest [] outstandingBuildRequests,
            string projectName
        )
        {
            this.targetId = new TargetIdWrapper(target);
            this.outstandingBuildRequests = outstandingBuildRequests;
            // For each waiting build context try to find the parent target
            this.parentBuildRequests = new List <BuildRequest>();
            this.parentTargets       = new List <TargetIdWrapper>();
            this.projectName         = projectName;

            // Process the waiting contexts if there are any
            if (waitingBuildStates != null)
            {
                for (int i = 0; i < waitingBuildStates.Count; i++)
                {
                    ProcessBuildContext(engineCallback, waitingBuildStates[i], target);
                }
            }
            // Process the initiating context
            ProcessBuildContext(engineCallback, initiatingRequest, target);
        }
Пример #2
0
        /// <summary>
        /// Given a build state try to find the parent target that caused this build state to
        /// come into being either via dependent, on error relationship or via IBuildEngine call
        /// </summary>
        internal TargetIdWrapper FindParentTarget
        (
            EngineCallback engineCallback,
            ProjectBuildState buildContext,
            Target target,
            out BuildRequest parentRequest
        )
        {
            // We need to find the parent target
            parentRequest = null;

            // Skip build states that have already been filled
            if (buildContext.CurrentBuildContextState == ProjectBuildState.BuildContextState.RequestFilled)
            {
                return(null);
            }

            // Check if the target was called due to a onerror or depends on call
            if (buildContext.ContainsBlockingTarget(target.Name))
            {
                // Figure out the record for the parent target
                Project containingProject = target.ParentProject;
                Target  parentTarget      = containingProject.Targets[buildContext.GetParentTarget(target.Name)];
                return(new TargetIdWrapper(parentTarget));
            }
            else
            {
                // The build context must have formed due to IBuildEngine call
                ErrorUtilities.VerifyThrow(
                    String.Compare(EscapingUtilities.UnescapeAll(buildContext.NameOfTargetInProgress), target.Name, StringComparison.OrdinalIgnoreCase) == 0,
                    "The target should be the in progress target for the context");
                // This target is called due to IBuildEngine or host request
                return(FindParentTargetForBuildRequest(engineCallback, buildContext.BuildRequest, out parentRequest));
            }
        }
Пример #3
0
        internal TargetCycleDetector(EngineLoggingServices engineLoggingService, EngineCallback engineCallback)
        {
            this.engineLoggingService = engineLoggingService;
            this.engineCallback       = engineCallback;

            dependencyGraph             = new Hashtable();
            outstandingExternalRequests = new Hashtable();
            cycleParent = null;
            cycleChild  = null;
        }
Пример #4
0
        /// <summary>
        /// Figure out the parent target or the parent build request for the given context
        /// </summary>
        private void ProcessBuildContext(EngineCallback engineCallback, ProjectBuildState buildContext, Target target)
        {
            BuildRequest    parentRequest = null;
            TargetIdWrapper parentName    = FindParentTarget(engineCallback, buildContext, target, out parentRequest);

            if (parentName != null)
            {
                parentTargets.Add(parentName);
            }
            if (parentRequest != null)
            {
                parentBuildRequests.Add(parentRequest);
            }
        }
Пример #5
0
        /// <summary>
        /// Given a build request try to find the target that caused it to come into being
        /// </summary>
        private TargetIdWrapper FindParentTargetForBuildRequest
        (
            EngineCallback engineCallback,
            BuildRequest triggeringBuildRequest,
            out BuildRequest parentTriggeringRequest
        )
        {
            parentTriggeringRequest = null;

            // If request is non-external and generated due to IBuildEngine call try
            // to find the target that caused the IBuildEngine call
            if (triggeringBuildRequest.IsGeneratedRequest && !triggeringBuildRequest.IsExternalRequest)
            {
                ExecutionContext executionContext =
                    engineCallback.GetExecutionContextFromHandleId(triggeringBuildRequest.HandleId);

                // If the parent context is not a routing context than we can
                // get the parent target from it
                if (executionContext is TaskExecutionContext)
                {
                    return(new TargetIdWrapper(((TaskExecutionContext)executionContext).ParentTarget));
                }
                // If the parent context if a routing context the parent target is not available
                // on the current node, so store the request instead
                else
                {
                    parentTriggeringRequest = triggeringBuildRequest;
                }
            }
            // If the request is external to the node - store the request since the parent target
            // is not available
            else if (triggeringBuildRequest.IsExternalRequest)
            {
                parentTriggeringRequest = triggeringBuildRequest;
            }
            else
            {
                requestedByHost = true;
            }

            return(null);
        }
Пример #6
0
        /// <summary>
        /// The TaskExecutionModule is a the external view into a subsystem responsible for executing user
        /// tasks. The subsystem consists of TaskWorkerThread, TaskEngine, TaskExecutionState and EngineProxy.
        /// The engine thread passes the TaskExecutionState to the TEM which after the task finishes passes the
        /// results back via the engineCallback.
        /// </summary>
        internal TaskExecutionModule
        (
            EngineCallback engineCallback,
            TaskExecutionModuleMode moduleMode,
            bool profileExecution
        )
        {
            this.engineCallback = engineCallback;
            this.moduleMode     = moduleMode;
            // By default start in breadthFirst traversal. This is done to gather enough work at the start of the build to get all the nodes at least working on something.
            this.breadthFirstTraversal = true;
            this.profileExecution      = profileExecution;
            this.totalTaskTime         = 0;
            // Get the node the TEM is running on, this is so the parent engine knows which node is requesting a traversal strategy change.
            nodeId = engineCallback.GetParentEngine().NodeId;

            SetBatchRequestSize();

            // In singleproc mode the task execution module executes tasks on the engine thread. In multi proc mode a new thread is
            // created so the TEM can submit tasks to a worker queue which will run the tasks on a new thread.
            if (moduleMode != TaskExecutionModuleMode.SingleProcMode)
            {
                this.isRunningMultipleNodes  = true;
                this.activeThreadCount       = 0;
                this.overallThreadCount      = 0;
                this.threadActiveCountEvent  = new ManualResetEvent(false);
                this.threadOverallCountEvent = new ManualResetEvent(false);
                this.lastTaskActivity        = 0;

                // Create a worker thread and make it the active node thread
                workerThread = new TaskWorkerThread(this, profileExecution);
                workerThread.ActivateThread();
            }
            else
            {
                this.isRunningMultipleNodes = false;
            }
        }
Пример #7
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);
        }