Exemple #1
0
        /// <summary>
        /// Dispatches the packet to the correct handler.
        /// </summary>
        private void HandlePacket(INodePacket packet)
        {
            switch (packet.Type)
            {
                case NodePacketType.BuildRequest:
                    HandleBuildRequest(packet as BuildRequest);
                    break;

                case NodePacketType.BuildRequestConfiguration:
                    HandleBuildRequestConfiguration(packet as BuildRequestConfiguration);
                    break;

                case NodePacketType.BuildRequestConfigurationResponse:
                    HandleBuildRequestConfigurationResponse(packet as BuildRequestConfigurationResponse);
                    break;

                case NodePacketType.BuildRequestUnblocker:
                    HandleBuildResult(packet as BuildRequestUnblocker);
                    break;

                case NodePacketType.NodeConfiguration:
                    HandleNodeConfiguration(packet as NodeConfiguration);
                    break;

                case NodePacketType.NodeBuildComplete:
                    HandleNodeBuildComplete(packet as NodeBuildComplete);
                    break;
            }
        }
Exemple #2
0
        /// <summary>
        /// This method handles the asynchronous message pump.  It waits for messages to show up on the queue
        /// and calls FireDataAvailable for each such packet.  It will terminate when the terminate event is
        /// set.
        /// </summary>
        private void PacketPumpProc()
        {
            try
            {
                // Ordering of the wait handles is important.  The first signalled wait handle in the array
                // will be returned by WaitAny if multiple wait handles are signalled.  We prefer to have the
                // terminate event triggered so that we cannot get into a situation where packets are being
                // spammed to the endpoint and it never gets an opportunity to shutdown.
                WaitHandle[] handles = new WaitHandle[] { _terminatePacketPump, _packetAvailable };

                bool exitLoop = false;
                do
                {
                    int waitId = WaitHandle.WaitAny(handles);
                    switch (waitId)
                    {
                    case 0:
                        exitLoop = true;
                        break;

                    case 1:
                    {
                        // Figure out how many packets are currently in the queue to process.  We
                        // will only process the number in the queue at this moment so that we don't
                        // get into a condition where the sending thread continues to pump packets in
                        // as fast as we can send them, potentially starving us from detecting a
                        // terminate event.
                        int packets = 0;
                        lock (_packetQueue)
                        {
                            packets = _packetQueue.Count;
                        }

                        while (packets > 0)
                        {
                            // Grab the first packet in the queue.
                            INodePacket packet = null;

                            lock (_packetQueue)
                            {
                                ErrorUtilities.VerifyThrow(_packetQueue.Count > 0, "Packet Queue count is zero.");
                                packet = _packetQueue.Dequeue();
                            }

                            _peerEndpoint._packetFactory.RoutePacket(0, packet);
                            --packets;
                        }
                    }

                    break;

                    default:
                        ErrorUtilities.ThrowInternalError("waitId {0} out of range.", waitId);
                        break;
                    }
                }while (!exitLoop);
            }
            catch (Exception e)
            {
                // Dump all engine exceptions to a temp file
                // so that we have something to go on in the
                // event of a failure
                ExceptionHandling.DumpExceptionToFile(e);
                throw;
            }
        }
 /// <summary>
 /// Routes the specified packet.
 /// </summary>
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     PacketFactoryRecord record = _packetFactories[packet.Type];
     record.RoutePacket(nodeId, packet);
 }
        /// <summary>
        /// This method is invoked by the NodePacketRouter when a packet is received and is intended for
        /// this recipient.
        /// </summary>
        /// <param name="node">The node from which the packet was received.</param>
        /// <param name="packet">The packet.</param>
        public void PacketReceived(int node, INodePacket packet)
        {
            if (_nodeIdToPacketHandler.ContainsKey(node))
            {
                _nodeIdToPacketHandler[node].PacketReceived(node, packet);
            }
            else
            {
                ErrorUtilities.VerifyThrow(packet.Type == NodePacketType.NodeShutdown, "We should only ever handle packets of type NodeShutdown -- everything else should only come in when there's an active task");

                // May also be removed by unnatural termination, so don't assume it's there
                lock (_activeNodes)
                {
                    if (_activeNodes.Contains(node))
                    {
                        _activeNodes.Remove(node);
                    }

                    if (_activeNodes.Count == 0)
                    {
                        _noNodesActiveEvent.Set();
                    }
                }
            }
        }
 /// <summary>
 /// This method is invoked by the NodePacketRouter when a packet is received and is intended for
 /// this recipient.
 /// </summary>
 /// <param name="node">The node from which the packet was received.</param>
 /// <param name="packet">The packet.</param>
 public void PacketReceived(int node, INodePacket packet)
 {
     lock (_receivedPackets)
     {
         _receivedPackets.Enqueue(packet);
         _packetReceivedEvent.Set();
     }
 }
 /// <summary>
 /// Sends data to the specified node.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="packet">The packet to send.</param>
 public void SendData(int node, INodePacket packet)
 {
     throw new NotSupportedException("not used");
 }
 /// <summary>
 /// Sends data to the specified node.
 /// </summary>
 /// <param name="context">The node to which data shall be sent.</param>
 /// <param name="packet">The packet to send.</param>
 protected void SendData(NodeContext context, INodePacket packet)
 {
     ErrorUtilities.VerifyThrowArgumentNull(packet, "packet");
     context.SendData(packet);
 }
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     throw new NotSupportedException("not used");
 }
 public void SendData(int node, INodePacket packet)
 {
     throw new NotSupportedException("not used");
 }
 /// <summary>
 /// Create a method which will be a fake method to process a packet.
 /// This needs to be done because using an anonymous method does not work.
 /// Using an anonymous method does not work because when the delegate is created
 /// it seems that a field is created which creates a strong reference
 /// between the delegate and the class it was created in. This means the delegate is not
 /// garbage collected until the class it was instantiated in is collected itself.
 /// </summary>
 /// <param name="packet">Packet to process</param>
 private static void PacketProcessor(INodePacket packet)
 {
 }
Exemple #11
0
 private static bool IsExitPacket(INodePacket packet)
 {
     return(packet is NodeBuildComplete buildCompletePacket && !buildCompletePacket.PrepareForReuse);
 }
        /// <summary>
        /// Routes the specified packet.
        /// </summary>
        public void RoutePacket(int nodeId, INodePacket packet)
        {
            PacketFactoryRecord record = _packetFactories[packet.Type];

            record.RoutePacket(nodeId, packet);
        }
 /// <summary>
 /// Routes the packet to the correct destination.
 /// </summary>
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     _handler.PacketReceived(nodeId, packet);
 }
            /// <summary>
            /// Creates a packet from a binary stream and sends it to the registered handler.
            /// </summary>
            public void DeserializeAndRoutePacket(int nodeId, INodePacketTranslator translator)
            {
                INodePacket packet = _factoryMethod(translator);

                RoutePacket(nodeId, packet);
            }
        /// <summary>
        /// Sends data to the peer endpoint.
        /// </summary>
        /// <param name="packet">The packet to send.</param>
        public void SendData(INodePacket packet)
        {
            ErrorUtilities.VerifyThrow(_status == LinkStatus.Active, "Cannot send when link status is not active. Current status {0}", _status);

            if (_mode == EndpointMode.Synchronous)
            {
                _peerEndpoint._packetFactory.RoutePacket(0, packet);
            }
            else
            {
                EnqueuePacket(packet);
            }
        }
Exemple #16
0
 /// <summary>
 /// Create a method which will be a fake method to process a packet.
 /// This needs to be done because using an anonymous method does not work.
 /// Using an anonymous method does not work because when the delegate is created
 /// it seems that a field is created which creates a strong reference
 /// between the delegate and the class it was created in. This means the delegate is not
 /// garbage collected until the class it was instantiated in is collected itself.
 /// </summary>
 /// <param name="packet">Packet to process</param>
 private void PacketProcessor(INodePacket packet)
 {
 }
Exemple #17
0
        /// <summary>
        /// Will receive a logging packet and send it to the correct
        /// sink which is registered to the LoggingServices.
        /// PacketReceived should be called from a single thread.
        /// </summary>
        /// <param name="node">The node from which the packet was received.</param>
        /// <param name="packet">A LogMessagePacket</param>
        /// <exception cref="InternalErrorException">Packet is null</exception>
        /// <exception cref="InternalErrorException">Packet is not a NodePacketType.LogMessage</exception>
        public void PacketReceived(int node, INodePacket packet)
        {
            // The packet cannot be null
            ErrorUtilities.VerifyThrow(packet != null, "packet was null");

            // Expected the packet type to be a logging message packet
            // PERF: Not using VerifyThrow to avoid allocations for enum.ToString (boxing of NodePacketType) in the non-error case.
            if (packet.Type != NodePacketType.LogMessage)
            {
                ErrorUtilities.ThrowInternalError("Expected packet type \"{0}\" but instead got packet type \"{1}\".", NodePacketType.LogMessage.ToString(), packet.Type.ToString());
            }

            LogMessagePacket loggingPacket = (LogMessagePacket)packet;
            InjectNonSerializedData(loggingPacket);
            ProcessLoggingEvent(loggingPacket.NodeBuildEvent, allowThrottling: true);
        }
        /// <summary>
        /// Sends data to the specified node.
        /// </summary>
        /// <param name="nodeId">The node to which data shall be sent.</param>
        /// <param name="packet">The packet to send.</param>
        public void SendData(int nodeId, INodePacket packet)
        {
            ErrorUtilities.VerifyThrow(_nodeContexts.ContainsKey(nodeId), "Invalid node id specified: {0}.", nodeId);

            SendData(_nodeContexts[nodeId], packet);
        }
        /// <summary>
        /// Adds a packet to the packet queue when asynchronous mode is enabled.
        /// </summary>
        /// <param name="packet">The packet to be transmitted.</param>
        private void EnqueuePacket(INodePacket packet)
        {
            ErrorUtilities.VerifyThrowArgumentNull(packet, "packet");
            ErrorUtilities.VerifyThrow(null != _packetQueue, "packetQueue is null");
            ErrorUtilities.VerifyThrow(null != _packetAvailable, "packetAvailable is null");

            lock (_packetQueue)
            {
                _packetQueue.Enqueue(packet);
                _packetAvailable.Set();
            }
        }
Exemple #20
0
 /// <summary>
 /// This method is invoked by the NodePacketRouter when a packet is received and is intended for
 /// this recipient.
 /// </summary>
 /// <param name="node">The node from which the packet was received.</param>
 /// <param name="packet">The packet.</param>
 public void PacketReceived(int node, INodePacket packet)
 {
     _receivedPackets.Enqueue(packet);
     _packetReceivedEvent.Set();
 }
        /// <summary>
        /// Sends data to the specified node.
        /// </summary>
        /// <param name="hostContext">The node to which data shall be sent.</param>
        /// <param name="packet">The packet to send.</param>
        public void SendData(TaskHostContext hostContext, INodePacket packet)
        {
            ErrorUtilities.VerifyThrow(_nodeContexts.ContainsKey(hostContext), "Invalid host context specified: {0}.", hostContext.ToString());

            SendData(_nodeContexts[hostContext], packet);
        }
Exemple #22
0
 /// <summary>
 /// Callback for logging packets to be sent.
 /// </summary>
 private void SendLoggingPacket(INodePacket packet)
 {
     if (_nodeEndpoint.LinkStatus == LinkStatus.Active)
     {
         _nodeEndpoint.SendData(packet);
     }
 }
        /// <summary>
        /// Routes a packet.
        /// </summary>
        /// <param name="nodeId">The id of the node from which the packet is being routed.</param>
        /// <param name="packet">The packet to route.</param>
        public void RoutePacket(int nodeId, INodePacket packet)
        {
            INodePacketFactory factory = _packetFactory;

            if (_inProcNodeId != InvalidInProcNodeId)
            {
                // If this was a shutdown packet, we are done with the node.  Release all context associated with it.  Do this here, rather
                // than after we route the packet, because otherwise callbacks to the NodeManager to determine if we have available nodes
                // will report that the in-proc node is still in use when it has actually shut down.
                int savedInProcNodeId = _inProcNodeId;
                if (packet.Type == NodePacketType.NodeShutdown)
                {
                    _inProcNodeId = InvalidInProcNodeId;

                    // Release the operating environment semaphore if we were holding it.
                    if ((_componentHost.BuildParameters.SaveOperatingEnvironment) &&
                        (_inProcNodeOwningOperatingEnvironment != null))
                    {
                        _inProcNodeOwningOperatingEnvironment.Release();
                        _inProcNodeOwningOperatingEnvironment.Close();
                        _inProcNodeOwningOperatingEnvironment = null;
                    }

                    if (!_componentHost.BuildParameters.EnableNodeReuse)
                    {
                        _inProcNode = null;
                        _inProcNodeEndpoint = null;
                        _inProcNodeThread = null;
                        _packetFactory = null;
                    }
                }

                // Route the packet back to the NodeManager.
                factory.RoutePacket(savedInProcNodeId, packet);
            }
        }
Exemple #24
0
        /// <summary>
        /// Dispatches the packet to the correct handler.
        /// </summary>
        private void HandlePacket(INodePacket packet)
        {
            // Console.WriteLine("Handling packet {0} at {1}", packet.Type, DateTime.Now);
            switch (packet.Type)
            {
                case NodePacketType.BuildRequest:
                    HandleBuildRequest(packet as BuildRequest);
                    break;

                case NodePacketType.BuildRequestConfiguration:
                    HandleBuildRequestConfiguration(packet as BuildRequestConfiguration);
                    break;

                case NodePacketType.BuildRequestConfigurationResponse:
                    HandleBuildRequestConfigurationResponse(packet as BuildRequestConfigurationResponse);
                    break;

                case NodePacketType.BuildRequestUnblocker:
                    HandleBuildRequestUnblocker(packet as BuildRequestUnblocker);
                    break;

                case NodePacketType.NodeConfiguration:
                    HandleNodeConfiguration(packet as NodeConfiguration);
                    break;

                case NodePacketType.NodeBuildComplete:
                    HandleNodeBuildComplete(packet as NodeBuildComplete);
                    break;
            }
        }
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     _dataReceivedContext = new DataReceivedContext(Thread.CurrentThread, packet);
     _dataReceivedEvent.Set();
 }
Exemple #26
0
 /// <summary>
 /// Sends data to the specified node.
 /// </summary>
 /// <param name="nodeId">The node to which data shall be sent.</param>
 /// <param name="packet">The packet to send.</param>
 public void SendData(int nodeId, INodePacket packet)
 {
     throw new NotImplementedException("Use the other overload of SendData instead");
 }
 /// <summary>
 /// Routes the packet to the correct destination.
 /// </summary>
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     _handler.PacketReceived(nodeId, packet);
 }
Exemple #28
0
        /// <summary>
        /// Sends data to the specified node.
        /// </summary>
        /// <param name="hostContext">The node to which data shall be sent.</param>
        /// <param name="packet">The packet to send.</param>
        public void SendData(TaskHostContext hostContext, INodePacket packet)
        {
            ErrorUtilities.VerifyThrow(_nodeContexts.ContainsKey(hostContext), "Invalid host context specified: {0}.", hostContext.ToString());

            SendData(_nodeContexts[hostContext], packet);
        }
 /// <summary>
 /// Create a method which will be a fake method to process a packet.
 /// This needs to be done because using an anonymous method does not work. 
 /// Using an anonymous method does not work because when the delegate is created
 /// it seems that a field is created which creates a strong reference
 /// between the delegate and the class it was created in. This means the delegate is not
 /// garbage collected until the class it was instantiated in is collected itself.
 /// </summary>
 /// <param name="packet">Packet to process</param>
 private void PacketProcessor(INodePacket packet)
 {
 }
Exemple #30
0
        /// <summary>
        /// Starts up the node and processes messages until the node is requested to shut down.
        /// </summary>
        /// <param name="shutdownException">The exception which caused shutdown, if any.</param>
        /// <returns>The reason for shutting down.</returns>
        public NodeEngineShutdownReason Run(out Exception shutdownException)
        {
#if !CLR2COMPATIBILITY
            _registeredTaskObjectCache = new RegisteredTaskObjectCacheBase();
#endif
            shutdownException = null;

            // Snapshot the current environment
            _savedEnvironment = CommunicationsUtilities.GetEnvironmentVariables();

            string pipeName = "MSBuild" + Process.GetCurrentProcess().Id;

            _nodeEndpoint = new NodeEndpointOutOfProcTaskHost(pipeName);
            _nodeEndpoint.OnLinkStatusChanged += new LinkStatusChangedDelegate(OnLinkStatusChanged);
            _nodeEndpoint.Listen(this);

            WaitHandle[] waitHandles = new WaitHandle[] { _shutdownEvent, _packetReceivedEvent, _taskCompleteEvent, _taskCancelledEvent };

            while (true)
            {
                int index = WaitHandle.WaitAny(waitHandles);
                switch (index)
                {
                case 0:     // shutdownEvent
                    NodeEngineShutdownReason shutdownReason = HandleShutdown();
                    return(shutdownReason);

                case 1:     // packetReceivedEvent
                    INodePacket packet = null;

                    int packetCount = _receivedPackets.Count;

                    while (packetCount > 0)
                    {
                        lock (_receivedPackets)
                        {
                            if (_receivedPackets.Count > 0)
                            {
                                packet = _receivedPackets.Dequeue();
                            }
                            else
                            {
                                break;
                            }
                        }

                        if (packet != null)
                        {
                            HandlePacket(packet);
                        }
                    }

                    break;

                case 2:     // taskCompleteEvent
                    CompleteTask();
                    break;

                case 3:     // taskCancelledEvent
                    CancelTask();
                    break;
                }
            }

            // UNREACHABLE
        }
        /// <summary>
        /// Sends data to the specified node.
        /// </summary>
        /// <param name="nodeId">The node to which data shall be sent.</param>
        /// <param name="packet">The packet to send.</param>
        public void SendData(int nodeId, INodePacket packet)
        {
            ErrorUtilities.VerifyThrow(_nodeContexts.ContainsKey(nodeId), "Invalid node id specified: {0}.", nodeId);

            SendData(_nodeContexts[nodeId], packet);
        }
            /// <summary>
            /// Sends the specified packet to this node.
            /// </summary>
            /// <param name="packet">The packet to send.</param>
            public void SendData(INodePacket packet)
            {
                MemoryStream          writeStream     = new MemoryStream();
                INodePacketTranslator writeTranslator = NodePacketTranslator.GetWriteTranslator(writeStream);

                try
                {
                    writeStream.WriteByte((byte)packet.Type);

                    // Pad for the packet length
                    writeStream.Write(BitConverter.GetBytes((int)0), 0, 4);
                    packet.Translate(writeTranslator);

                    // Now plug in the real packet length
                    writeStream.Position = 1;
                    writeStream.Write(BitConverter.GetBytes((int)writeStream.Length - 5), 0, 4);

#if FALSE
                    if (trace) // Avoid method call
                    {
                        CommunicationsUtilities.Trace(nodeId, "Sending Packet of type {0} with length {1}", packet.Type.ToString(), writeStream.Length - 5);
                    }
#endif

                    byte[] writeStreamBuffer = writeStream.GetBuffer();

                    for (int i = 0; i < writeStream.Length; i += MaxPacketWriteSize)
                    {
                        int lengthToWrite = Math.Min((int)writeStream.Length - i, MaxPacketWriteSize);
                        if ((int)writeStream.Length - i <= MaxPacketWriteSize)
                        {
                            // We are done, write the last bit asynchronously.  This is actually the general case for
                            // most packets in the build, and the asynchronous behavior here is desirable.
#if FEATURE_APM
                            _serverToClientStream.BeginWrite(writeStreamBuffer, i, lengthToWrite, PacketWriteComplete, null);
#else
                            _serverToClientStream.WriteAsync(writeStreamBuffer, i, lengthToWrite);
#endif
                            return;
                        }
                        else
                        {
                            // If this packet is longer that we can write in one go, then we need to break it up.  We can't
                            // return out of this function and let the rest of the system continue because another operation
                            // might want to send data immediately afterward, and that could result in overlapping writes
                            // to the pipe on different threads.
#if FEATURE_APM
                            IAsyncResult result = _serverToClientStream.BeginWrite(writeStream.GetBuffer(), i, lengthToWrite, null, null);
                            _serverToClientStream.EndWrite(result);
#else
                            _serverToClientStream.Write(writeStreamBuffer, i, lengthToWrite);
#endif
                        }
                    }
                }
                catch (IOException e)
                {
                    // Do nothing here because any exception will be caught by the async read handler
                    CommunicationsUtilities.Trace(_nodeId, "EXCEPTION in SendData: {0}", e);
                }
                catch (ObjectDisposedException) // This happens if a child dies unexpectedly
                {
                    // Do nothing here because any exception will be caught by the async read handler
                }
            }
        /// <summary>
        /// Adds a packet to the packet queue when asynchronous mode is enabled.
        /// </summary>
        /// <param name="packet">The packet to be transmitted.</param>
        private void EnqueuePacket(INodePacket packet)
        {
            ErrorUtilities.VerifyThrowArgumentNull(packet, "packet");
            ErrorUtilities.VerifyThrow(_mode == EndpointMode.Asynchronous, "EndPoint mode is synchronous, should be asynchronous");
            ErrorUtilities.VerifyThrow(null != _packetQueue, "packetQueue is null");
            ErrorUtilities.VerifyThrow(null != _packetAvailable, "packetAvailable is null");

            lock (_packetQueue)
            {
                _packetQueue.Enqueue(packet);
                _packetAvailable.Set();
            }
        }
 /// <summary>
 /// Sends data to the specified node.
 /// </summary>
 /// <param name="context">The node to which data shall be sent.</param>
 /// <param name="packet">The packet to send.</param>
 protected void SendData(NodeContext context, INodePacket packet)
 {
     ErrorUtilities.VerifyThrowArgumentNull(packet, "packet");
     context.SendData(packet);
 }
 /// <summary>
 /// Routes the specified packet. This is called by the Inproc node directly since it does not have to do any deserialization
 /// </summary>
 /// <param name="nodeId">The node from which the packet was received.</param>
 /// <param name="packet">The packet to route.</param>
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     throw new NotSupportedException("not used");
 }
Exemple #36
0
 /// <summary>
 /// Called when a packet has been received.
 /// </summary>
 /// <param name="node">The node from which the packet was received.</param>
 /// <param name="packet">The packet.</param>
 void INodePacketHandler.PacketReceived(int node, INodePacket packet)
 {
     _receivedPackets.Enqueue(packet);
     _packetReceivedEvent.Set();
 }
 /// <summary>
 /// Sends data to the peer endpoint.
 /// </summary>
 /// <param name="packet">The packet to send.</param>
 public void SendData(INodePacket packet)
 {
     // PERF: Set up a priority system so logging packets are sent only when all other packet types have been sent.
     if (_status == LinkStatus.Active)
     {
         EnqueuePacket(packet);
     }
 }
Exemple #38
0
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     _dataReceivedContext = new DataReceivedContext(Thread.CurrentThread, packet);
     _dataReceivedEvent.Set();
 }
            /// <summary>
            /// Sends the specified packet to this node.
            /// </summary>
            /// <param name="packet">The packet to send.</param>
            public void SendData(INodePacket packet)
            {
                MemoryStream writeStream = new MemoryStream();
                INodePacketTranslator writeTranslator = NodePacketTranslator.GetWriteTranslator(writeStream);
                try
                {
                    writeStream.WriteByte((byte)packet.Type);

                    // Pad for the packet length
                    writeStream.Write(BitConverter.GetBytes((int)0), 0, 4);
                    packet.Translate(writeTranslator);

                    // Now plug in the real packet length
                    writeStream.Position = 1;
                    writeStream.Write(BitConverter.GetBytes((int)writeStream.Length - 5), 0, 4);

#if FALSE
                    if (trace) // Avoid method call
                    {
                        CommunicationsUtilities.Trace(nodeId, "Sending Packet of type {0} with length {1}", packet.Type.ToString(), writeStream.Length - 5);
                    }
#endif

                    for (int i = 0; i < writeStream.Length; i += MaxPacketWriteSize)
                    {
                        int lengthToWrite = Math.Min((int)writeStream.Length - i, MaxPacketWriteSize);
                        if ((int)writeStream.Length - i <= MaxPacketWriteSize)
                        {
                            // We are done, write the last bit asynchronously.  This is actually the general case for
                            // most packets in the build, and the asynchronous behavior here is desirable.
                            _nodePipe.BeginWrite(writeStream.GetBuffer(), i, lengthToWrite, PacketWriteComplete, null);
                            return;
                        }
                        else
                        {
                            // If this packet is longer that we can write in one go, then we need to break it up.  We can't
                            // return out of this function and let the rest of the system continue because another operation
                            // might want to send data immediately afterward, and that could result in overlapping writes
                            // to the pipe on different threads.
                            IAsyncResult result = _nodePipe.BeginWrite(writeStream.GetBuffer(), i, lengthToWrite, null, null);
                            _nodePipe.EndWrite(result);
                        }
                    }
                }
                catch (IOException e)
                {
                    // Do nothing here because any exception will be caught by the async read handler
                    CommunicationsUtilities.Trace(_nodeId, "EXCEPTION in SendData: {0}", e);
                }
                catch (ObjectDisposedException) // This happens if a child dies unexpectedly
                {
                    // Do nothing here because any exception will be caught by the async read handler
                }
            }
Exemple #40
0
 public DataReceivedContext(Thread thread, INodePacket packet)
 {
     this.thread = thread;
     this.packet = packet;
 }
 /// <summary>
 /// Sends data to the specified node.
 /// </summary>
 /// <param name="nodeId">The node to which data shall be sent.</param>
 /// <param name="packet">The packet to send.</param>
 public void SendData(int nodeId, INodePacket packet)
 {
     throw new NotImplementedException("Use the other overload of SendData instead");
 }
Exemple #42
0
        /// <summary>
        /// Executes the task.
        /// </summary>
        public bool Execute()
        {
            // log that we are about to spawn the task host
            string runtime      = _taskHostParameters[XMakeAttributes.runtime];
            string architecture = _taskHostParameters[XMakeAttributes.architecture];

            _taskLoggingContext.LogComment(MessageImportance.Low, "ExecutingTaskInTaskHost", _taskType.Type.Name, _taskType.Assembly.AssemblyLocation, runtime, architecture);

            // set up the node
            lock (_taskHostLock)
            {
                _taskHostProvider = (NodeProviderOutOfProcTaskHost)_buildComponentHost.GetComponent(BuildComponentType.OutOfProcTaskHostNodeProvider);
                ErrorUtilities.VerifyThrowInternalNull(_taskHostProvider, "taskHostProvider");
            }

            TaskHostConfiguration hostConfiguration =
                new TaskHostConfiguration
                (
                    _buildComponentHost.BuildParameters.NodeId,
                    NativeMethodsShared.GetCurrentDirectory(),
                    CommunicationsUtilities.GetEnvironmentVariables(),
                    _buildComponentHost.BuildParameters.Culture,
                    _buildComponentHost.BuildParameters.UICulture,
#if FEATURE_APPDOMAIN
                    _appDomainSetup,
#endif
                    BuildEngine.LineNumberOfTaskNode,
                    BuildEngine.ColumnNumberOfTaskNode,
                    BuildEngine.ProjectFileOfTaskNode,
                    BuildEngine.ContinueOnError,
                    _taskType.Type.FullName,
                    AssemblyUtilities.GetAssemblyLocation(_taskType.Type.GetTypeInfo().Assembly),
                    _setParameters,
                    new Dictionary <string, string>(_buildComponentHost.BuildParameters.GlobalProperties),
                    _taskLoggingContext.GetWarningsAsErrors(),
                    _taskLoggingContext.GetWarningsAsMessages()

                );

            try
            {
                lock (_taskHostLock)
                {
                    _requiredContext     = CommunicationsUtilities.GetHandshakeOptions(taskHost: true, taskHostParameters: _taskHostParameters);
                    _connectedToTaskHost = _taskHostProvider.AcquireAndSetUpHost(_requiredContext, this, this, hostConfiguration);
                }

                if (_connectedToTaskHost)
                {
                    try
                    {
                        bool taskFinished = false;

                        while (!taskFinished)
                        {
                            _packetReceivedEvent.WaitOne();

                            INodePacket packet = null;

                            // Handle the packet that's coming in
                            while (_receivedPackets.TryDequeue(out packet))
                            {
                                if (packet != null)
                                {
                                    HandlePacket(packet, out taskFinished);
                                }
                            }
                        }
                    }
                    finally
                    {
                        lock (_taskHostLock)
                        {
                            _taskHostProvider.DisconnectFromHost(_requiredContext);
                            _connectedToTaskHost = false;
                        }
                    }
                }
                else
                {
                    LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, null);
                }
            }
            catch (BuildAbortedException)
            {
                LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, null);
            }
            catch (NodeFailedToLaunchException e)
            {
                LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, e);
            }

            return(_taskExecutionSucceeded);
        }
 /// <summary>
 /// Routes the specified packet
 /// </summary>
 /// <param name="nodeId">The node from which the packet was received.</param>
 /// <param name="packet">The packet to route.</param>
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     if (_nodeIdToPacketFactory.ContainsKey(nodeId))
     {
         _nodeIdToPacketFactory[nodeId].RoutePacket(nodeId, packet);
     }
     else
     {
         _localPacketFactory.RoutePacket(nodeId, packet);
     }
 }
Exemple #44
0
 /// <summary>
 /// Routes the specified packet
 /// </summary>
 /// <param name="nodeId">The node from which the packet was received.</param>
 /// <param name="packet">The packet to route.</param>
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     _packetFactory.RoutePacket(nodeId, packet);
 }
        /// <summary>
        /// Sends data to the specified node.
        /// </summary>
        /// <param name="nodeId">The node to which data should be sent.</param>
        /// <param name="packet">The data to send.</param>
        public void SendData(int nodeId, INodePacket packet)
        {
            ErrorUtilities.VerifyThrowArgumentOutOfRange(nodeId == _inProcNodeId, "node");
            ErrorUtilities.VerifyThrowArgumentNull(packet, "packet");

            if (null == _inProcNode)
            {
                return;
            }

            _inProcNodeEndpoint.SendData(packet);
        }
Exemple #46
0
        /// <summary>
        /// Handles the packets received from the task host. 
        /// </summary>
        private void HandlePacket(INodePacket packet, out bool taskFinished)
        {
            Debug.WriteLine("[TaskHostTask] Handling packet {0} at {1}", packet.Type, DateTime.Now);
            taskFinished = false;

            switch (packet.Type)
            {
                case NodePacketType.TaskHostTaskComplete:
                    HandleTaskHostTaskComplete(packet as TaskHostTaskComplete);
                    taskFinished = true;
                    break;
                case NodePacketType.NodeShutdown:
                    HandleNodeShutdown(packet as NodeShutdown);
                    taskFinished = true;
                    break;
                case NodePacketType.LogMessage:
                    HandleLoggedMessage(packet as LogMessagePacket);
                    break;
                default:
                    ErrorUtilities.ThrowInternalErrorUnreachable();
                    break;
            }
        }
 /// <summary>
 /// Routes the specified packet
 /// </summary>
 /// <param name="nodeId">The node from which the packet was received.</param>
 /// <param name="packet">The packet to route.</param>
 public void RoutePacket(int nodeId, INodePacket packet)
 {
     _packetFactory.RoutePacket(nodeId, packet);
 }
Exemple #48
0
        /// <summary>
        /// Sends data to the specified node.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="packet">The packet to send.</param>
        public void SendData(int node, INodePacket packet)
        {
            // Look up the node provider for this node in the mapping.
            INodeProvider provider = null;
            if (!_nodeIdToProvider.TryGetValue(node, out provider))
            {
                ErrorUtilities.ThrowInternalError("Node {0} does not have a provider.", node);
            }

            // Send the data.
            provider.SendData(node, packet);
        }
 /// <summary>
 /// Dispatches the packet to the correct handler.
 /// </summary>
 private void HandlePacket(INodePacket packet)
 {
     switch (packet.Type)
     {
         case NodePacketType.TaskHostConfiguration:
             HandleTaskHostConfiguration(packet as TaskHostConfiguration);
             break;
         case NodePacketType.TaskHostTaskCancelled:
             _taskCancelledEvent.Set();
             break;
         case NodePacketType.NodeBuildComplete:
             HandleNodeBuildComplete(packet as NodeBuildComplete);
             break;
     }
 }
Exemple #50
0
        /// <summary>
        /// Routes the specified packet. This is called by the Inproc node directly since it does not have to do any deserialization
        /// </summary>
        /// <param name="nodeId">The node from which the packet was received.</param>
        /// <param name="packet">The packet to route.</param>
        public void RoutePacket(int nodeId, INodePacket packet)
        {
            if (packet.Type == NodePacketType.NodeShutdown)
            {
                RemoveNodeFromMapping(nodeId);
            }

            _packetFactory.RoutePacket(nodeId, packet);
        }
 public DataReceivedContext(Thread thread, INodePacket packet)
 {
     this.thread = thread;
     this.packet = packet;
 }
Exemple #52
0
 /// <inheritdoc cref="INodePacketHandler.PacketReceived"/>
 ///
 public abstract void PacketReceived(int node, INodePacket packet);