예제 #1
0
        /// <summary>
        /// This class is an implementation of IEngineCallback which is used on the child nodes
        /// </summary>
        internal LocalNodeCallback(ManualResetEvent exitCommunicationThreads, LocalNode localNode)
        {
            this.localNode = localNode;
            this.exitCommunicationThreads = exitCommunicationThreads;

            this.nodeCommandQueue = new DualQueue<LocalCallDescriptor>();
            this.nodeHiPriCommandQueue = new DualQueue<LocalCallDescriptor>();

            // Initalize the reply infrastructur
            this.repliesFromParent = new Hashtable();
        }
예제 #2
0
 /// <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);
 }
예제 #3
0
 /// <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);
 }
예제 #4
0
 /// <summary>
 /// Appropriate action to take if this event is received on the child process
 /// </summary>
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     for (int i = 0; i < buildRequests.Length; i++)
     {
         node.PostBuildRequest(buildRequests[i]);
     }
 }
예제 #5
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     // No node action here, we do our thing in GetReplyData
 }
예제 #6
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     node.Introspector.BreakCycle(child, parent);
 }
예제 #7
0
파일: LocalNode.cs 프로젝트: nikson/msbuild
        /// <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();
         }
예제 #8
0
 /// <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");
 }
예제 #9
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     localNode.Activate(environmentVariables, nodeLoggers, nodeId, parentGlobalProperties,
                        toolsetSearchLocations, parentProcessId, parentStartupDirectory);
 }
예제 #10
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     localNode.ShutdownNode(shutdownLevel, exitProcess, false);
 }
예제 #11
0
 /// <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);
 }
예제 #12
0
 /// <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);
 }
예제 #13
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     // No node action here, we do our thing in GetReplyData
 }
예제 #14
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     node.Introspector.BreakCycle(child, parent);
 }
예제 #15
0
        /// <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)
                    {
                        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();
        }
예제 #16
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     localNode.ShutdownNode(shutdownLevel, exitProcess, false);
 }
예제 #17
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     localNode.Activate(environmentVariables, nodeLoggers, nodeId, parentGlobalProperties, 
                        toolsetSearchLocations, parentProcessId, parentStartupDirectory);
 }
예제 #18
0
 /// <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");
 }
예제 #19
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     node.RequestStatus(requestId);
 }
예제 #20
0
 internal override void NodeAction(Node node, LocalNode localNode)
 {
     node.RequestStatus(requestId);
 }