/// <summary> /// Appropriate action to take if this event is received on the child process /// </summary> internal virtual void NodeAction(Node node, LocalNode localNode) { ErrorUtilities.VerifyThrow(false, "This description doesn't support this operation"); }
internal override void NodeAction(Node node, LocalNode localNode) { node.RequestStatus(requestId); }
internal override void NodeAction(Node node, LocalNode localNode) { localNode.ShutdownNode(shutdownLevel, exitProcess, false); }
internal override void NodeAction(Node node, LocalNode localNode) { localNode.Activate(environmentVariables, nodeLoggers, nodeId, parentGlobalProperties, toolsetSearchLocations, parentProcessId, parentStartupDirectory); }
/// <summary> /// UNDONE - need to verified after logging spec /// </summary> internal override void NodeAction(Node node, LocalNode localNode) { ErrorUtilities.VerifyThrowArgumentNull(node, "node is null"); node.UpdateNodeSettings(logOnlyCriticalEvents, centralizedLogging, useBreadthFirstTraversal); }
/// <summary> /// Appropriate action to take if this event is received on the child process /// </summary> internal override void NodeAction(Node node, LocalNode localNode) { node.PostBuildResult(buildResult); }
internal override void NodeAction(Node node, LocalNode localNode) { // No node action here, we do our thing in GetReplyData }
internal override void NodeAction(Node node, LocalNode localNode) { node.Introspector.BreakCycle(child, parent); }
/// <summary> /// This function starts local node when process is launched and shuts it down on time out /// Called by msbuild.exe. /// </summary> public static void StartLocalNodeServer(int nodeNumber) { // Create global events necessary for handshaking with the parent if (!CreateGlobalEvents(nodeNumber)) { return; } LocalNode localNode = new LocalNode(nodeNumber); WaitHandle[] waitHandles = new WaitHandle[4]; waitHandles[0] = shutdownEvent; waitHandles[1] = globalNodeErrorShutdown; waitHandles[2] = inUseEvent; waitHandles[3] = globalInitiateActivationEvent; // This is necessary to make build.exe finish promptly. Dont remove. if (!Engine.debugMode) { // Create null streams for the current input/output/error streams Console.SetOut(new StreamWriter(Stream.Null)); Console.SetError(new StreamWriter(Stream.Null)); Console.SetIn(new StreamReader(Stream.Null)); } bool continueRunning = true; while (continueRunning) { int eventType = WaitHandle.WaitAny(waitHandles, inactivityTimeout, false); if (eventType == 0 || eventType == 1 || eventType == WaitHandle.WaitTimeout) { continueRunning = false; localNode.ShutdownNode(eventType != 1 ? Node.NodeShutdownLevel.PoliteShutdown : Node.NodeShutdownLevel.ErrorShutdown, true, true); } else if (eventType == 2) { // reset the event as we do not want it to go into this state again when we are done with this if statement. inUseEvent.Reset(); // The parent knows at this point the child process has been launched globalNodeActivate.Reset(); // Set the global inuse event so other parent processes know this node is now initialized globalNodeInUse.Set(); // Make a copy of the parents handle to protect ourselves in case the parent dies, // this is to prevent a parent from reserving a node another parent is trying to use. globalNodeReserveHandle = new EventWaitHandle(false, EventResetMode.ManualReset, LocalNodeProviderGlobalNames.NodeReserveEventName(nodeNumber)); WaitHandle[] waitHandlesActive = new WaitHandle[3]; waitHandlesActive[0] = shutdownEvent; waitHandlesActive[1] = globalNodeErrorShutdown; waitHandlesActive[2] = notInUseEvent; eventType = WaitHandle.WaitTimeout; while (eventType == WaitHandle.WaitTimeout && continueRunning == true) { eventType = WaitHandle.WaitAny(waitHandlesActive, parentCheckInterval, false); if (eventType == 0 || /* nice shutdown due to shutdownEvent */ eventType == 1 || /* error shutdown due to globalNodeErrorShutdown */ eventType == WaitHandle.WaitTimeout && !localNode.IsParentProcessAlive()) { continueRunning = false; // If the exit is not triggered by running of shutdown method if (eventType != 0) { localNode.ShutdownNode(Node.NodeShutdownLevel.ErrorShutdown, true, true); } } else if (eventType == 2) { // Trigger a collection before the node goes idle to insure that // the memory is released to the system as soon as possible GC.Collect(); // Change the current directory to a safe one so that the directory // last used by the build can be safely deleted. We must have read // access to the safe directory so use SystemDirectory for this purpose. Directory.SetCurrentDirectory(Environment.SystemDirectory); notInUseEvent.Reset(); globalNodeInUse.Reset(); } } ErrorUtilities.VerifyThrow(localNode.node == null, "Expected either node to be null or continueRunning to be false."); // Stop the communication threads and release the shared memory object so that the next parent can create it localNode.StopCommunicationThreads(); // Close the local copy of the reservation handle (this allows another parent to reserve // the node) globalNodeReserveHandle.Close(); globalNodeReserveHandle = null; } else if (eventType == 3) { globalInitiateActivationEvent.Reset(); localNode.StartCommunicationThreads(); globalNodeActivate.Set(); } } // Stop the communication threads and release the shared memory object so that the next parent can create it localNode.StopCommunicationThreads(); globalNodeActive.Close(); globalNodeInUse.Close(); }