/// <summary> /// Indicates to the EngineProxy that it is no longer needed. /// Called by TaskEngine when the task using the EngineProxy is done. /// </summary> internal void MarkAsInActive() { activeProxy = false; // Since the task has a pointer to this class it may store it in a static field. Null out // internal data so the leak of this object doesn't lead to a major memory leak. loggingServices = null; parentModule = null; buildEventContext = null; // Clear out the sponsor (who is responsible for keeping the EngineProxy remoting lease alive until the task is done) // this will be null if the engineproxy was never sent accross an appdomain boundry. if (sponsor != null) { ILease lease = (ILease)RemotingServices.GetLifetimeService(this); if (lease != null) { lease.Unregister(sponsor); } sponsor.Close(); sponsor = null; } }
/// <summary> /// This constructor is used by the class internally to create new instances when a thread /// becomes blocked by a user code callback. /// </summary> private TaskWorkerThread ( TaskExecutionModule parentModule, ManualResetEvent exitTaskThreads, ExitTaskCache exitTaskThreadsCache, Queue <TaskWorkerThread> workerThreadQueue, Hashtable handleIdToWorkerThread, Queue <TaskExecutionState> workItemQueue, ManualResetEvent workItemInsertionEvent, Hashtable waitingTasks, bool profileExecution ) { this.parentModule = parentModule; this.exitTaskThreads = exitTaskThreads; this.exitTaskThreadsCache = exitTaskThreadsCache; this.workerThreadQueue = workerThreadQueue; this.handleIdToWorkerThread = handleIdToWorkerThread; this.workItemQueue = workItemQueue; this.workItemInsertionEvent = workItemInsertionEvent; this.waitingTasks = waitingTasks; this.profileExecution = profileExecution; InitializePerInstanceData(); }
/// <summary> /// Executes a task within a target. This method initializes a task engine for the given task, and then executes the task /// using the engine. /// </summary> /// <param name="taskNode"></param> /// <param name="hostObject"></param> /// <returns>true, if successful</returns> internal bool ExecuteOneTask(XmlElement taskNode, ITaskHost hostObject) { bool taskExecutedSuccessfully = false; string projectFileOfTaskNode = XmlUtilities.GetXmlNodeFile(taskNode, parentProject.FullFileName); BuildEventContext targetBuildEventContext = new BuildEventContext ( ParentProject.ProjectBuildEventContext.NodeId, this.id, ParentProject.ProjectBuildEventContext.ProjectContextId, ParentProject.ProjectBuildEventContext.TaskId ); int handleId = parentEngine.EngineCallback.CreateTaskContext(ParentProject, this, null, taskNode, EngineCallback.inProcNode, targetBuildEventContext); TaskExecutionModule taskExecutionModule = parentEngine.NodeManager.TaskExecutionModule; TaskEngine taskEngine = new TaskEngine(taskNode, hostObject, parentProject.FullFileName, projectFileOfTaskNode, parentEngine.LoggingServices, handleId, taskExecutionModule, targetBuildEventContext); taskExecutedSuccessfully = taskEngine.ExecuteTask ( TaskExecutionMode.ExecuteTaskAndGatherOutputs, new Lookup(parentProject.evaluatedItemsByName, parentProject.evaluatedProperties, ParentProject.ItemDefinitionLibrary) ); return(taskExecutedSuccessfully); }
/// <summary> /// This constructor creates a worker thread which is immediately ready to be activated. Once /// activated the thread will execute tasks as they appear in the work item queue. Once the /// thread is blocked from executing tasks it will pass the ownership of the work item queue to another /// thread /// </summary> internal TaskWorkerThread(TaskExecutionModule parentModule, bool profileExecution) { this.parentModule = parentModule; // Initialize the data that only has to be set by the very first thread // created by the TEM this.exitTaskThreads = new ManualResetEvent(false); this.exitTaskThreadsCache = new ExitTaskCache(false); this.workerThreadQueue = new Queue <TaskWorkerThread>(); this.handleIdToWorkerThread = new Hashtable(); this.workItemQueue = new Queue <TaskExecutionState>(); this.workItemInsertionEvent = new ManualResetEvent(false); this.waitingTasks = new Hashtable(); this.profileExecution = profileExecution; InitializePerInstanceData(); }
/// <summary> /// Default constructor. /// </summary> internal NodeManager(int cpuCount, bool childMode, Engine parentEngine) { nodeList = new List <ProvidersNodeInformation>(); nodeProviders = new List <INodeProvider>(); this.parentEngine = parentEngine; this.statusMessageReceived = new ManualResetEvent(false); // Create the inproc node, this means that there will always be one node, node 0 if (taskExecutionModule == null) { taskExecutionModule = new TaskExecutionModule(parentEngine.EngineCallback, (cpuCount == 1 && !childMode ? TaskExecutionModule.TaskExecutionModuleMode.SingleProcMode : TaskExecutionModule.TaskExecutionModuleMode.MultiProcFullNodeMode), parentEngine.ProfileBuild); } }
/// <summary> /// Create an instance of this class to represent the IBuildEngine2 interface to the task /// including the event location where the log messages are raised /// </summary> /// <param name="parentModule">Parent Task Execution Module</param> /// <param name="handleId"></param> /// <param name="parentProjectFullFileName">the full path to the currently building project</param> /// <param name="projectFileOfTaskNode">the path to the actual file (project or targets) where the task invocation is located</param> /// <param name="loggingServices"></param> /// <param name="buildEventContext">Event Context where events will be seen to be raised from. Task messages will get this as their event context</param> internal EngineProxy ( TaskExecutionModule parentModule, int handleId, string parentProjectFullFileName, string projectFileOfTaskNode, EngineLoggingServices loggingServices, BuildEventContext buildEventContext ) { ErrorUtilities.VerifyThrow(parentModule != null, "No parent module."); ErrorUtilities.VerifyThrow(loggingServices != null, "No logging services."); ErrorUtilities.VerifyThrow(projectFileOfTaskNode != null, "Need project file path string"); this.parentModule = parentModule; this.handleId = handleId; this.parentProjectFullFileName = parentProjectFullFileName; this.projectFileOfTaskNode = projectFileOfTaskNode; this.loggingServices = loggingServices; this.buildEventContext = buildEventContext; this.callbackMonitor = new object(); activeProxy = true; }