//returns false if the message was dropped because the max pending message count was hit.
        bool IUdpReceiveHandler.HandleDataReceived(ArraySegment <byte> data, EndPoint remoteEndpoint, int interfaceIndex, Action onMessageDequeuedCallback)
        {
            BufferManager localBufferManager = this.bufferManager;
            bool          returnBuffer       = true;
            string        messageHash        = null;
            Message       message            = null;
            bool          continueReceiving  = true;

            try
            {
                IPEndPoint remoteIPEndPoint = (IPEndPoint)remoteEndpoint;
                if (localBufferManager != null)
                {
                    message = UdpUtility.DecodeMessage(this.duplicateDetector, this.messageEncoderFactory.Encoder,
                                                       localBufferManager, data, remoteIPEndPoint, interfaceIndex, true, out messageHash);

                    if (message != null)
                    {
                        // We pass in the length of the message buffer instead of the length of the message to keep track of the amount of memory that's been allocated
                        continueReceiving = Dispatch(message, data.Array.Length, onMessageDequeuedCallback);
                        returnBuffer      = !continueReceiving;
                    }
                }
                else
                {
                    Fx.Assert(this.State != CommunicationState.Opened, "buffer manager should only be null when closing down and the channel instance has taken control of the receive manager.");

                    IUdpReceiveHandler receiveHandler = (IUdpReceiveHandler)this.channelInstance;

                    if (receiveHandler != null)
                    {
                        returnBuffer      = false; //let the channel instance take care of the buffer
                        continueReceiving = receiveHandler.HandleDataReceived(data, remoteEndpoint, interfaceIndex, onMessageDequeuedCallback);
                    }
                    else
                    {
                        //both channel and listener are shutting down, so drop the message and stop the receive loop
                        continueReceiving = false;
                    }
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    returnBuffer = false;
                    throw;
                }

                HandleReceiveException(e);
            }
            finally
            {
                if (returnBuffer)
                {
                    if (message != null)
                    {
                        if (this.duplicateDetector != null)
                        {
                            Fx.Assert(messageHash != null, "message hash should always be available if duplicate detector is enabled");
                            this.duplicateDetector.RemoveEntry(messageHash);
                        }

                        message.Close(); // implicitly returns the buffer
                    }
                    else
                    {
                        // CSDMain 238600. Both channel and listener are shutting down. There's a race condition happening here
                        // and the bufferManager is not available at this moment. The data buffer ignored here might introduce
                        // an issue with buffer manager, but given that we are in the shutting down case here, it should not be a
                        // big problem.
                        if (localBufferManager != null)
                        {
                            localBufferManager.ReturnBuffer(data.Array);
                        }
                    }
                }
            }

            return(continueReceiving);
        }
Ejemplo n.º 2
0
        // returns false if the message was dropped because the max pending message count was hit.
        bool IUdpReceiveHandler.HandleDataReceived(ArraySegment <byte> data, EndPoint remoteEndpoint, int interfaceIndex, Action onMessageDequeuedCallback)
        {
            bool    returnBuffer      = true;
            string  messageHash       = null;
            Message message           = null;
            bool    continueReceiving = true;

            try
            {
                IPEndPoint remoteIPEndPoint = (IPEndPoint)remoteEndpoint;

                message = UdpUtility.DecodeMessage(
                    this.DuplicateDetector,
                    this.Encoder,
                    this.BufferManager,
                    data,
                    remoteIPEndPoint,
                    interfaceIndex,
                    this.IgnoreSerializationException,
                    out messageHash);

                if (message != null)
                {
                    // We pass in the length of the message buffer instead of the length of the message to keep track of the amount of memory that's been allocated
                    continueReceiving = this.EnqueueMessage(message, data.Array.Length, onMessageDequeuedCallback);
                    returnBuffer      = !continueReceiving;
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    returnBuffer = false;
                    throw;
                }

                this.HandleReceiveException(e);
            }
            finally
            {
                if (returnBuffer)
                {
                    if (message != null)
                    {
                        if (this.DuplicateDetector != null)
                        {
                            Fx.Assert(messageHash != null, "message hash should always be available if duplicate detector is enabled");
                            this.DuplicateDetector.RemoveEntry(messageHash);
                        }

                        message.Close(); // implicitly returns the buffer
                    }
                    else
                    {
                        this.BufferManager.ReturnBuffer(data.Array);
                    }
                }
            }

            return(continueReceiving);
        }