/// <summary> /// Determine when the child node has either responsed with a shutdown complete event or the node has died /// </summary> internal bool ReadyToShutdown() { for (int i = 0; i < nodeData.Length; i++) { LocalNodeInfo nodeInfo = nodeData[i]; // Determine if the node is alive or dead, this check will set the processId to invalid if // the process is dead IsNodeProcessAliveOrUninitialized(i); // If any node is still alive and we have not recieved a shutdown response say we are not ready to shutdown if (nodeInfo.ProcessId > 0 && !nodeInfo.ShutdownResponseReceived) { return(false); } } return(true); }
public void Initialize ( string configuration, IEngineCallback parentEngineCallback, BuildPropertyGroup parentGlobalPropertyGroup, ToolsetDefinitionLocations toolSetSearchLocations, string startupDirectory ) { // Get from the environment how long we should wait in seconds for shutdown to complete string shutdownTimeoutFromEnvironment = Environment.GetEnvironmentVariable("MSBUILDNODESHUTDOWNTIMEOUT"); int result; if (int.TryParse(shutdownTimeoutFromEnvironment, out result) && result >= 0) { shutdownTimeout = result; } this.cpuCount = 1; if (configuration != null) { // Split out the parameter sets based on ; string[] parameters; parameters = configuration.Split(parameterDelimiters); // Go through each of the parameter name value pairs and split them appart for (int param = 0; param < parameters.Length; param++) { if (parameters[param].Length > 0) { string[] parameterComponents = parameters[param].Split(valueDelimiters); // If there is a name and value associated with the parameter, apply the paramter to the provider if (parameterComponents.Length == 2) { ApplyParameter(parameterComponents[0], parameterComponents[1]); } else // Only the parameter name is known, this could be for a boolean parameter { ApplyParameter(parameters[param], null); } } } } /* If we dont get a path passed in as a parameter, we can only assume that our path * is in the current appdomain basedirectory, this is the base directory * that the assembly resolver uses to probe for assemblies */ if (string.IsNullOrEmpty(this.locationOfMSBuildExe)) { this.locationOfMSBuildExe = AppDomain.CurrentDomain.BaseDirectory; } if ((cpuCount - 1) <= 0) { return; } this.exitCommunicationThreads = new ManualResetEvent(false); this.activeNodeCount = 0; this.responseCountChangeEvent = new ManualResetEvent(false); this.nodeStateLock = new object(); this.nodesToLaunch = new Queue <int>(); this.nodeLoggers = new List <LoggerDescription>(); nodeData = new LocalNodeInfo[cpuCount - 1]; // Initialize the internal state indicating that no nodes have been launched int lastUsedNodeNumber = 0; for (int i = 0; i < nodeData.Length; i++) { nodeData[i] = new LocalNodeInfo(lastUsedNodeNumber); lastUsedNodeNumber = nodeData[i].NodeNumber + 1; } // Set up the callback this.engineCallback = parentEngineCallback; this.parentGlobalProperties = parentGlobalPropertyGroup; this.toolsetSearchLocations = toolSetSearchLocations; this.startupDirectory = startupDirectory; // Default node settings centralizedLogging = false; onlyLogCriticalEvents = false; useBreadthFirstTraversal = true; shuttingDown = false; // Start the thread that will be processing the calls from the parent engine ThreadStart threadState = new ThreadStart(this.SharedMemoryWriterThread); Thread taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent->Child Writer"; taskThread.Start(); threadState = new ThreadStart(this.SharedMemoryReaderThread); taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent<-Child Reader"; taskThread.Start(); }
public void Initialize ( string configuration, IEngineCallback parentEngineCallback, BuildPropertyGroup parentGlobalPropertyGroup, ToolsetDefinitionLocations toolSetSearchLocations, string startupDirectory ) { // Get from the environment how long we should wait in seconds for shutdown to complete string shutdownTimeoutFromEnvironment = Environment.GetEnvironmentVariable("MSBUILDNODESHUTDOWNTIMEOUT"); int result; if (int.TryParse(shutdownTimeoutFromEnvironment, out result) && result >= 0) { shutdownTimeout = result; } this.cpuCount = 1; if (configuration != null) { // Split out the parameter sets based on ; string[] parameters; parameters = configuration.Split(parameterDelimiters); // Go through each of the parameter name value pairs and split them appart for (int param = 0; param < parameters.Length; param++) { if (parameters[param].Length > 0) { string[] parameterComponents = parameters[param].Split(valueDelimiters); // If there is a name and value associated with the parameter, apply the paramter to the provider if (parameterComponents.Length == 2) { ApplyParameter(parameterComponents[0], parameterComponents[1]); } else // Only the parameter name is known, this could be for a boolean parameter { ApplyParameter(parameters[param], null); } } } } /* If we dont get a path passed in as a parameter, we can only assume that our path is in the current appdomain basedirectory, this is the base directory that the assembly resolver uses to probe for assemblies */ if (string.IsNullOrEmpty(this.locationOfMSBuildExe)) { this.locationOfMSBuildExe = AppDomain.CurrentDomain.BaseDirectory; } if ( (cpuCount - 1) <= 0) { return; } this.exitCommunicationThreads = new ManualResetEvent(false); this.activeNodeCount = 0; this.responseCountChangeEvent = new ManualResetEvent(false); this.nodeStateLock = new object(); this.nodesToLaunch = new Queue<int>(); this.nodeLoggers = new List<LoggerDescription>(); nodeData = new LocalNodeInfo[cpuCount - 1]; // Initialize the internal state indicating that no nodes have been launched int lastUsedNodeNumber = 0; for (int i = 0; i < nodeData.Length; i++) { nodeData[i] = new LocalNodeInfo(lastUsedNodeNumber); lastUsedNodeNumber = nodeData[i].NodeNumber + 1; } // Set up the callback this.engineCallback = parentEngineCallback; this.parentGlobalProperties = parentGlobalPropertyGroup; this.toolsetSearchLocations = toolSetSearchLocations; this.startupDirectory = startupDirectory; // Default node settings centralizedLogging = false; onlyLogCriticalEvents = false; useBreadthFirstTraversal = true; shuttingDown = false; // Start the thread that will be processing the calls from the parent engine ThreadStart threadState = new ThreadStart(this.SharedMemoryWriterThread); Thread taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent->Child Writer"; taskThread.Start(); threadState = new ThreadStart(this.SharedMemoryReaderThread); taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent<-Child Reader"; taskThread.Start(); }