public void SetReceiveHandler(IUdpReceiveHandler handler)
 {
     Fx.Assert(handler != null, "IUdpReceiveHandler can't be null");
     Fx.Assert(handler.MaxReceivedMessageSize == this.receiveHandler.MaxReceivedMessageSize, "new receive handler's max message size doesn't match");
     Fx.Assert(this.openCount > 0, "SetReceiveHandler called on a closed UdpSocketReceiveManager");
     this.receiveHandler = handler;
 }
 public void SetReceiveHandler(IUdpReceiveHandler handler)
 {
     Fx.Assert(handler != null, "IUdpReceiveHandler can't be null");
     Fx.Assert(handler.MaxReceivedMessageSize == this.receiveHandler.MaxReceivedMessageSize, "new receive handler's max message size doesn't match");
     Fx.Assert(this.openCount > 0, "SetReceiveHandler called on a closed UdpSocketReceiveManager");
     this.receiveHandler = handler;
 }
        internal UdpSocketReceiveManager(UdpSocket[] receiveSockets, int maxPendingReceivesPerSocket, BufferManager bufferManager, IUdpReceiveHandler receiveHandler)
        {
            Fx.Assert(receiveSockets != null, "receiveSockets parameter is null");
            Fx.Assert(receiveSockets.Length > 0, "receiveSockets parameter is empty");
            Fx.Assert(maxPendingReceivesPerSocket > 0, "maxPendingReceivesPerSocket can't be <= 0");
            Fx.Assert(receiveHandler.MaxReceivedMessageSize > 0, "maxReceivedMessageSize must be > 0");
            Fx.Assert(bufferManager != null, "bufferManager argument should not be null");
            Fx.Assert(receiveHandler != null, "receiveHandler should not be null");

            this.receiveHandler = receiveHandler;
            this.thisLock = new object();
            this.bufferManager = bufferManager;
            this.receiveSockets = receiveSockets;
            this.maxPendingReceivesPerSocket = maxPendingReceivesPerSocket;
            this.messageBufferSize = UdpUtility.ComputeMessageBufferSize(receiveHandler.MaxReceivedMessageSize);

            int maxPendingReceives = maxPendingReceivesPerSocket * receiveSockets.Length;
            this.receiveBufferPool = new ConnectionBufferPool(this.messageBufferSize, maxPendingReceives);
        }
        internal UdpSocketReceiveManager(UdpSocket[] receiveSockets, int maxPendingReceivesPerSocket, BufferManager bufferManager, IUdpReceiveHandler receiveHandler)
        {
            Fx.Assert(receiveSockets != null, "receiveSockets parameter is null");
            Fx.Assert(receiveSockets.Length > 0, "receiveSockets parameter is empty");
            Fx.Assert(maxPendingReceivesPerSocket > 0, "maxPendingReceivesPerSocket can't be <= 0");
            Fx.Assert(receiveHandler.MaxReceivedMessageSize > 0, "maxReceivedMessageSize must be > 0");
            Fx.Assert(bufferManager != null, "bufferManager argument should not be null");
            Fx.Assert(receiveHandler != null, "receiveHandler should not be null");

            this.receiveHandler = receiveHandler;
            this.thisLock       = new object();
            this.bufferManager  = bufferManager;
            this.receiveSockets = receiveSockets;
            this.maxPendingReceivesPerSocket = maxPendingReceivesPerSocket;
            this.messageBufferSize           = UdpUtility.ComputeMessageBufferSize(receiveHandler.MaxReceivedMessageSize);

            int maxPendingReceives = maxPendingReceivesPerSocket * receiveSockets.Length;

            this.receiveBufferPool = new ConnectionBufferPool(this.messageBufferSize, maxPendingReceives);
        }
        //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);
        }