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