/// <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); }
/// <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); }
/// <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); }
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); }
/// <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)); }
/// <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); }