Пример #1
0
        /// <summary>
        /// The Activate method is invoked to instruct the IPC module
        /// to start asynchronously processing IO.
        /// </summary>
        public void Activate()
        {
            if (_moduleState == ModuleStates.Module_State_Shutdown)
            {
                _moduleState = ModuleStates.Module_State_Active;

                // REC: Disable the Nagle algorithm:
                _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);

                // REC: Dispatch the Event_Opened event to the
                // module's owner:
                EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                if (tmp != null)
                {
                    tmp(this, new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Opened));
                }

                // REC: Initiate the first receive operation against the
                // socket associated with the module. As receive operations
                // complete, the completion handler will take care of all the
                // subsequent IO context generation / management:
                IoContext rxContext = new IoContext(_socket, new VfxMsgBlock(8192));
                InitiateRecv(rxContext);
            }
        }
Пример #2
0
        /// <summary>
        /// The Shutdown method is invoked to instruct the module
        /// to terminate the connection to the peer system. If the
        /// graceful flag is set to true, then the module will wait
        /// until all pending I/O operations are completed before
        /// </summary>
        /// <param name="graceful"></param>
        public void Shutdown(bool graceful)
        {
            if (_moduleState == ModuleStates.Module_State_Active)
            {
                _moduleState = ModuleStates.Module_State_Closing;

                if (graceful == false)
                {
                    // REC: Remove all pending send operations
                    // from the queue and return their buffers
                    // to the buffer pool:
                    lock (_synchTxContextQueue)
                    {
                        while (_txContextQueue.Count > 0)
                        {
                            IoContext txContext = _txContextQueue.Dequeue();
                            txContext._ipcBuffer.RdIndex = 0;
                            txContext._ipcBuffer.WrIndex = 0;

                            lock (_synchIoContextQueue)
                            {
                                _ioContextQueue.Enqueue(txContext);
                            }
                        }
                    }

                    // REC: Close the socket that is being
                    // used to send data to the client:
                    _socket.Close();
                }
                else
                {
                }
            }
        }
Пример #3
0
        private OneStateTransition GetOneChangeTransition(SystemState anotherSystemState)
        {
            var transitionPairs = ModuleStates
                                  .Zip(anotherSystemState.ModuleStates, (from, to) => new OneStateTransition(from, to))
                                  .ToList();

            var notEqualPairs = transitionPairs.Where(pair => !pair.From.Equals(pair.To)).ToList();

            if (notEqualPairs.Count != 1)
            {
                return(null);
            }

            var transition = notEqualPairs.Single();

            return(transition.From.IsValidStateChangeTo(transition.To) ? transition : null);
        }
Пример #4
0
        public ModuleInfo(string name, string installedVersion, string currentVersion, Guid?moduleId = null)
        {
            _name             = name;
            _installedVersion = installedVersion;
            _currentVersion   = currentVersion;
            _moduleId         = moduleId;

            if (installedVersion == null)
            {
                _status = ModuleStates.NotYetInstalled;
            }
            else if (_currentVersion == null)
            {
                _status = ModuleStates.Unreferenced;
            }
            else if (installedVersion == _currentVersion)
            {
                _status = ModuleStates.UpToDate;
            }
            else
            {
                _status = ModuleStates.ToBeUpdated;
            }
        }
Пример #5
0
 public override string ToString() => $"[{string.Join("", ModuleStates.Select(state => state.ToString()))}]";
Пример #6
0
        /// <summary>
        /// The CompleteRecv method is invoked in response to
        /// an asynchronous receive operation completing.
        /// </summary>
        /// <param name="ar"></param>
        private void CompleteRecv(IAsyncResult ar)
        {
            // REC: Retrieve the IO context that is associated with the
            // original asynchronous receive operation.
            IoContext rxContext = ar.AsyncState as IoContext;

            if (rxContext != null)
            {
                try
                {
                    // REC: Get the total number of bytes that were read
                    // from the peer system by this operation:
                    int rxBytes = rxContext._ipcSocket.EndReceive(ar);
                    if (rxBytes > 0)
                    {
                        // REC: Adjust the write index in the message block:
                        rxContext._ipcBuffer.WrIndex = rxContext._ipcBuffer.WrIndex + rxBytes;

                        // REC: Offload the received data onto a separate thread:
                        if (this._rxBuffering == true)
                        {
                            Socket rxSocket = rxContext._ipcSocket;
                            lock (this._synchRxPendingQueue)
                            {
                                // REC: Push the received data onto the queue so that
                                // it can be picked up by the secondary receive thread
                                // for further processing:
                                this._rxPendingQueue.Enqueue(rxContext);

                                // REC: If the queue was empty prior to this context
                                // being added to it, we need to signal the secondary
                                // receive thread so that it can start processing the
                                // data again:
                                if (this._rxPendingQueue.Count == 1)
                                {
                                    this._eventRxBuffer.Set();
                                }
                            }

                            // REC: Attempt to pull another context from the context
                            // queue so that we can receive more data:
                            IoContext rxNext;
                            if (this._rxContextQueue.Count > 0)
                            {
                                rxNext = this._rxContextQueue.Dequeue();
                            }
                            else
                            {
                                // REC: Note that this is BAD and will result in the
                                // exhaustion of all the system's memory if there is a
                                // continuous problem with the speed at which messages
                                // are being consumed on the receive thread...
                                rxNext = new IoContext(rxSocket, new VfxMsgBlock(8192));
                            }

                            // REC: Initiate a new receive operation, using the next
                            // available receive context:
                            InitiateRecv(rxNext);
                        }
                        else
                        {
                            // REC: If receive buffering has not been enabled then the
                            // data is dispatched directly to the module's owner:
                            EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                            if (tmp != null)
                            {
                                tmp(this, new VfxIpcEventArgs(rxContext._ipcBuffer));

                                // REC: Adjust the buffer to take into consideration
                                // any data that was read by the module's owner:
                                rxContext._ipcBuffer.Crunch();

                                // REC: Initiate another receive operation using the
                                // same receive buffer that was just processed:
                                InitiateRecv(rxContext);
                            }
                        }
                    }
                    else
                    {
                        _moduleState = ModuleStates.Module_State_Shutdown;

                        // REC: This might happen as the result of the
                        // user closing the session down.
                        EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                        if (tmp != null)
                        {
                            VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                            tmp(this, dxArgs);
                        }
                    }
                }
                catch (SocketException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This might happen as the result of the
                    // user closing the session down.
                    EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
                catch (ObjectDisposedException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This happens if the socket gets closed
                    // locally rather than being closed by the peer.
                    EventHandler <VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        /// The CompleteSend event handler is invoked in response to an
        /// asynchronous send operation being completed. The system reacts
        /// to the completion by finalizing the asynchronous operation and
        /// then starting a new one.
        /// </summary>
        /// <param name="ar"></param>
        private void CompleteSend(IAsyncResult ar)
        {
            IoContext ctx = ar.AsyncState as IoContext;

            if (ctx != null)
            {
                int txBytes = ctx._ipcSocket.EndSend(ar);
                if (txBytes > 0)
                {
                    // REC: If the system did not transmit all of the data
                    // that was in the IO context buffer then it initiates
                    // a new send operation against the residual content:
                    if (txBytes < ctx._ipcBuffer.Length())
                    {
                        // REC: Adjust the read index...
                        ctx._ipcBuffer.RdIndex += txBytes;
                        ctx._ipcBuffer.Crunch();

                        // REC: and try to send it again...
                        InitiateSend(ctx, true);
                    }
                    else
                    {
                        lock (_synchIoContextQueue)
                        {
                            // REC: Reset the message block's
                            // read and write indices:
                            ctx._ipcBuffer.RdIndex = 0;
                            ctx._ipcBuffer.WrIndex = 0;

                            // REC: Return the buffer to the
                            // pool so it can be used again:
                            _ioContextQueue.Enqueue(ctx);

                            // REC: If there were no contexts remaining
                            // in the transmit queue when this one was
                            // returned to it, trigger the buffer event
                            // so that HandleTx can acquire one:
                            if (_ioContextQueue.Count == 1)
                            {
                                _eventTxBuffer.Set();
                            }
                        }

                        lock (_synchTxContextQueue)
                        {
                            if (_txContextQueue.Count > 0)
                            {
                                IoContext next = _txContextQueue.Dequeue();
                                InitiateSend(next, true);
                            }
                            else
                            {
                                _txPending = false;

                                // REC: If the module is being shutdown
                                // and there are no further pending sends
                                // left to process, generate the shutdown
                                // event to notify the module's owner:
                                if (_moduleState == ModuleStates.Module_State_Closing)
                                {
                                    _moduleState = ModuleStates.Module_State_Shutdown;
                                    // REC: Close the socket to ensure that the
                                    // disconnect event is triggered:
                                    _socket.Close();
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #8
0
        /// <summary>
        /// The CompleteSend event handler is invoked in response to an
        /// asynchronous send operation being completed. The system reacts
        /// to the completion by finalizing the asynchronous operation and
        /// then starting a new one.
        /// </summary>
        /// <param name="ar"></param>
        private void CompleteSend(IAsyncResult ar)
        {
            IoContext ctx = ar.AsyncState as IoContext;
            if (ctx != null)
            {
                int txBytes = ctx._ipcSocket.EndSend(ar);
                if (txBytes > 0)
                {
                    // REC: If the system did not transmit all of the data
                    // that was in the IO context buffer then it initiates
                    // a new send operation against the residual content:
                    if (txBytes < ctx._ipcBuffer.Length())
                    {
                        // REC: Adjust the read index...
                        ctx._ipcBuffer.RdIndex += txBytes;
                        ctx._ipcBuffer.Crunch();

                        // REC: and try to send it again...
                        InitiateSend(ctx, true);
                    }
                    else
                    {
                        lock (_synchIoContextQueue)
                        {
                            // REC: Reset the message block's
                            // read and write indices:
                            ctx._ipcBuffer.RdIndex = 0;
                            ctx._ipcBuffer.WrIndex = 0;

                            // REC: Return the buffer to the
                            // pool so it can be used again:
                            _ioContextQueue.Enqueue(ctx);

                            // REC: If there were no contexts remaining
                            // in the transmit queue when this one was
                            // returned to it, trigger the buffer event
                            // so that HandleTx can acquire one:
                            if (_ioContextQueue.Count == 1)
                            {
                                _eventTxBuffer.Set();
                            }
                        }

                        lock (_synchTxContextQueue)
                        {
                            if (_txContextQueue.Count > 0)
                            {
                                IoContext next = _txContextQueue.Dequeue();
                                InitiateSend(next, true);
                            }
                            else
                            {
                                _txPending = false;

                                // REC: If the module is being shutdown
                                // and there are no further pending sends
                                // left to process, generate the shutdown
                                // event to notify the module's owner:
                                if (_moduleState == ModuleStates.Module_State_Closing)
                                {
                                    _moduleState = ModuleStates.Module_State_Shutdown;
                                    // REC: Close the socket to ensure that the
                                    // disconnect event is triggered:
                                    _socket.Close();
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
        /// <summary>
        /// The CompleteRecv method is invoked in response to
        /// an asynchronous receive operation completing.
        /// </summary>
        /// <param name="ar"></param>
        private void CompleteRecv(IAsyncResult ar)
        {
            // REC: Retrieve the IO context that is associated with the
            // original asynchronous receive operation.
            IoContext rxContext = ar.AsyncState as IoContext;
            if (rxContext != null)
            {
                try
                {
                    // REC: Get the total number of bytes that were read
                    // from the peer system by this operation:
                    int rxBytes = rxContext._ipcSocket.EndReceive(ar);
                    if (rxBytes > 0)
                    {
                        // REC: Adjust the write index in the message block:
                        rxContext._ipcBuffer.WrIndex = rxContext._ipcBuffer.WrIndex + rxBytes;

                        // REC: Offload the received data onto a separate thread:
                        if (this._rxBuffering == true)
                        {
                            Socket rxSocket = rxContext._ipcSocket;
                            lock (this._synchRxPendingQueue)
                            {
                                // REC: Push the received data onto the queue so that
                                // it can be picked up by the secondary receive thread
                                // for further processing:
                                this._rxPendingQueue.Enqueue(rxContext);

                                // REC: If the queue was empty prior to this context
                                // being added to it, we need to signal the secondary
                                // receive thread so that it can start processing the
                                // data again:
                                if (this._rxPendingQueue.Count == 1)
                                {
                                    this._eventRxBuffer.Set();
                                }
                            }

                            // REC: Attempt to pull another context from the context
                            // queue so that we can receive more data:
                            IoContext rxNext;
                            if (this._rxContextQueue.Count > 0)
                            {
                                rxNext = this._rxContextQueue.Dequeue();
                            }
                            else
                            {
                                // REC: Note that this is BAD and will result in the
                                // exhaustion of all the system's memory if there is a
                                // continuous problem with the speed at which messages
                                // are being consumed on the receive thread...
                                rxNext = new IoContext(rxSocket, new VfxMsgBlock(8192));
                            }

                            // REC: Initiate a new receive operation, using the next
                            // available receive context:
                            InitiateRecv(rxNext);
                        }
                        else
                        {
                            // REC: If receive buffering has not been enabled then the
                            // data is dispatched directly to the module's owner:
                            EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                            if (tmp != null)
                            {
                                tmp(this, new VfxIpcEventArgs(rxContext._ipcBuffer));

                                // REC: Adjust the buffer to take into consideration
                                // any data that was read by the module's owner:
                                rxContext._ipcBuffer.Crunch();

                                // REC: Initiate another receive operation using the
                                // same receive buffer that was just processed:
                                InitiateRecv(rxContext);
                            }
                        }
                    }
                    else
                    {
                        _moduleState = ModuleStates.Module_State_Shutdown;

                        // REC: This might happen as the result of the
                        // user closing the session down.
                        EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                        if (tmp != null)
                        {
                            VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                            tmp(this, dxArgs);
                        }
                    }
                }
                catch (SocketException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This might happen as the result of the
                    // user closing the session down.
                    EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
                catch (ObjectDisposedException)
                {
                    _moduleState = ModuleStates.Module_State_Shutdown;

                    // REC: This happens if the socket gets closed
                    // locally rather than being closed by the peer.
                    EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                    if (tmp != null)
                    {
                        VfxIpcEventArgs dxArgs = new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Closed);
                        tmp(this, dxArgs);
                    }
                }
            }
        }
Пример #10
0
        /// <summary>
        /// The Shutdown method is invoked to instruct the module
        /// to terminate the connection to the peer system. If the
        /// graceful flag is set to true, then the module will wait
        /// until all pending I/O operations are completed before 
        /// </summary>
        /// <param name="graceful"></param>
        public void Shutdown(bool graceful)
        {
            if (_moduleState == ModuleStates.Module_State_Active)
            {
                _moduleState = ModuleStates.Module_State_Closing;

                if (graceful == false)
                {
                    // REC: Remove all pending send operations
                    // from the queue and return their buffers
                    // to the buffer pool:
                    lock (_synchTxContextQueue)
                    {
                        while (_txContextQueue.Count > 0)
                        {
                            IoContext txContext = _txContextQueue.Dequeue();
                            txContext._ipcBuffer.RdIndex = 0;
                            txContext._ipcBuffer.WrIndex = 0;

                            lock (_synchIoContextQueue)
                            {
                                _ioContextQueue.Enqueue(txContext);
                            }
                        }
                    }

                    // REC: Close the socket that is being
                    // used to send data to the client:
                    _socket.Close();
                }
                else
                {

                }
            }
        }
Пример #11
0
        /// <summary>
        /// The Activate method is invoked to instruct the IPC module
        /// to start asynchronously processing IO.
        /// </summary>
        public void Activate()
        {
            if (_moduleState == ModuleStates.Module_State_Shutdown)
            {
                _moduleState = ModuleStates.Module_State_Active;

                // REC: Disable the Nagle algorithm:
                _socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);

                // REC: Dispatch the Event_Opened event to the
                // module's owner:
                EventHandler<VfxIpcEventArgs> tmp = EventDispatch;
                if (tmp != null)
                {
                    tmp(this, new VfxIpcEventArgs(VfxIpcEventTypes.Event_Session_Opened));
                }

                // REC: Initiate the first receive operation against the
                // socket associated with the module. As receive operations
                // complete, the completion handler will take care of all the
                // subsequent IO context generation / management:
                IoContext rxContext = new IoContext(_socket, new VfxMsgBlock(8192));
                InitiateRecv(rxContext);
            }
        }