Exemplo n.º 1
0
        /// <summary>
        /// Receive a message. The <c>Recv</c> method calls this lower-level method to do the actual receiving.
        /// </summary>
        /// <param name="msg">the <c>Msg</c> to receive the message into</param>
        /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
        protected override bool XRecv(ref Msg msg)
        {
            if (m_receivingState == State.Data)
            {
                msg.Move(ref m_prefetchedMsg);
                m_receivingState = State.RoutingId;

                return(true);
            }

            var pipe = new Pipe[1];

            bool isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg);

            // Drop any messages with more flag
            while (isMessageAvailable && msg.HasMore)
            {
                // drop all frames of the current multi-frame message
                isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg);

                while (isMessageAvailable && msg.HasMore)
                {
                    isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg);
                }

                // get the new message
                isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg);
            }

            if (!isMessageAvailable)
            {
                return(false);
            }

            Debug.Assert(pipe[0] != null);

            // We are at the beginning of a message.
            // Keep the message part we have in the prefetch buffer
            // and return the ID of the peer instead.
            m_prefetchedMsg.Move(ref msg);

            byte[] routingId = pipe[0].RoutingId;
            msg.InitPool(routingId.Length);
            msg.Put(routingId, 0, routingId.Length);
            msg.SetFlags(MsgFlags.More);
            m_receivingState = State.Data;

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Receive a message. The <c>Recv</c> method calls this lower-level method to do the actual receiving.
        /// </summary>
        /// <param name="msg">the <c>Msg</c> to receive the message into</param>
        /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
        protected override bool XRecv(ref Msg msg)
        {
            bool received = m_fairQueueing.RecvPipe(ref msg, out var pipe);

            // Drop any messages with more flag
            while (received && msg.HasMore)
            {
                // drop all frames of the current multi-frame message
                received = m_fairQueueing.Recv(ref msg);

                while (received && msg.HasMore)
                {
                    received = m_fairQueueing.Recv(ref msg);
                }

                // get the new message
                if (received)
                {
                    received = m_fairQueueing.RecvPipe(ref msg, out pipe);
                }
            }

            if (!received)
            {
                return(false);
            }

            Assumes.NotNull(pipe);
            msg.RoutingId = pipe.RoutingId;

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Receive a message. The <c>Recv</c> method calls this lower-level method to do the actual receiving.
        /// </summary>
        /// <param name="msg">the <c>Msg</c> to receive the message into</param>
        /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
        protected override bool XRecv(ref Msg msg)
        {
            if (m_prefetched)
            {
                if (!m_identitySent)
                {
                    msg.Move(ref m_prefetchedId);
                    m_identitySent = true;
                }
                else
                {
                    msg.Move(ref m_prefetchedMsg);
                    m_prefetched = false;
                }

                return(true);
            }

            var pipe = new Pipe[1];

            bool isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref m_prefetchedMsg);

            if (!isMessageAvailable)
            {
                return(false);
            }

            Debug.Assert(pipe[0] != null);
            Debug.Assert(!m_prefetchedMsg.HasMore);

            // We have received a frame with TCP data.
            // Rather than sending this frame, we keep it in prefetched
            // buffer and send a frame with peer's ID.
            byte[] identity = pipe[0].Identity;
            msg.InitPool(identity.Length);
            msg.Put(identity, 0, identity.Length);
            msg.SetFlags(MsgFlags.More);

            m_prefetched   = true;
            m_identitySent = true;

            return(true);
        }
Exemplo n.º 4
0
        protected override bool XRecv(SendReceiveOptions flags, ref Msg msg)
        {
            if (m_prefetched)
            {
                if (!m_identitySent)
                {
                    msg.Move(ref m_prefetchedId);
                    m_identitySent = true;
                }
                else
                {
                    msg.Move(ref m_prefetchedMsg);
                    m_prefetched = false;
                }
                m_moreIn = msg.HasMore;
                return(true);
            }

            var pipe = new Pipe[1];

            bool isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg);

            //  It's possible that we receive peer's identity. That happens
            //  after reconnection. The current implementation assumes that
            //  the peer always uses the same identity.
            while (isMessageAvailable && msg.IsIdentity)
            {
                isMessageAvailable = m_fairQueueing.RecvPipe(pipe, ref msg);
            }

            if (!isMessageAvailable)
            {
                return(false);
            }

            Debug.Assert(pipe[0] != null);

            //  If we are in the middle of reading a message, just return the next part.
            if (m_moreIn)
            {
                m_moreIn = msg.HasMore;
            }
            else
            {
                //  We are at the beginning of a message.
                //  Keep the message part we have in the prefetch buffer
                //  and return the ID of the peer instead.
                m_prefetchedMsg.Move(ref msg);

                m_prefetched = true;

                byte[] identity = pipe[0].Identity;
                msg.InitPool(identity.Length);
                msg.Put(identity, 0, identity.Length);
                msg.SetFlags(MsgFlags.More);

                m_identitySent = true;
            }

            return(true);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Get a message from FairQueuing data structure
 /// </summary>
 /// <param name="msg">a Msg to receive the message into</param>
 /// <param name="pipe">a specific Pipe to receive on</param>
 /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
 protected bool XRecvPipe(ref Msg msg, out Pipe pipe)
 {
     return(m_fairQueueing.RecvPipe(ref msg, out pipe));
 }
Exemplo n.º 6
0
        /// <summary>
        /// Receive a message. The <c>Recv</c> method calls this lower-level method to do the actual receiving.
        /// </summary>
        /// <param name="msg">the <c>Msg</c> to receive the message into</param>
        /// <returns><c>true</c> if the message was received successfully, <c>false</c> if there were no messages to receive</returns>
        protected override bool XRecv(ref Msg msg)
        {
            if (m_prefetched)
            {
                if (!m_identitySent)
                {
                    msg.Move(ref m_prefetchedId);
                    m_identitySent = true;
                }
                else
                {
                    msg.Move(ref m_prefetchedMsg);
                    m_prefetched = false;
                }
                m_moreIn = msg.HasMore;

                if (!m_moreIn)
                {
                    if (m_closingCurrentIn)
                    {
                        Assumes.NotNull(m_currentIn);
                        m_currentIn.Terminate(true);
                        m_closingCurrentIn = false;
                    }
                    m_currentIn = null;
                }

                return(true);
            }

            bool isMessageAvailable = m_fairQueueing.RecvPipe(ref msg, out Pipe? pipe);

            // It's possible that we receive peer's identity. That happens
            // after reconnection. The current implementation assumes that
            // the peer always uses the same identity.
            while (isMessageAvailable && msg.IsIdentity)
            {
                isMessageAvailable = m_fairQueueing.RecvPipe(ref msg, out pipe);
            }

            if (!isMessageAvailable)
            {
                return(false);
            }

            Assumes.NotNull(pipe);

            // If we are in the middle of reading a message, just return the next part.
            if (m_moreIn)
            {
                m_moreIn = msg.HasMore;

                if (!m_moreIn)
                {
                    if (m_closingCurrentIn)
                    {
                        Assumes.NotNull(m_currentIn);
                        m_currentIn.Terminate(true);
                        m_closingCurrentIn = false;
                    }
                    m_currentIn = null;
                }
            }
            else
            {
                // We are at the beginning of a message.
                // Keep the message part we have in the prefetch buffer
                // and return the ID of the peer instead.
                m_prefetchedMsg.Move(ref msg);

                m_prefetched = true;
                m_currentIn  = pipe;

                Assumes.NotNull(pipe.Identity);

                byte[] identity = pipe.Identity;
                msg.InitPool(identity.Length);
                msg.Put(identity, 0, identity.Length);
                msg.SetFlags(MsgFlags.More);

                m_identitySent = true;
            }

            return(true);
        }