protected override void OnOpened() { this.channelQueue = new InputQueue <TChannel>(); Fx.Assert(this.socketReceiveManager == null, "receive manager shouldn't be initialized yet"); this.socketReceiveManager = new UdpSocketReceiveManager(this.listenSockets.ToArray(), UdpConstants.PendingReceiveCountPerProcessor * Environment.ProcessorCount, this.bufferManager, this); //do the state change to CommunicationState.Opened before starting the receive loop. //this avoids a ---- between transitioning state and processing messages that are //already in the socket receive buffer. base.OnOpened(); this.socketReceiveManager.Open(); }
void Cleanup() { if (Interlocked.Increment(ref this.cleanedUp) == 1) { lock (this.ThisLock) { if (this.socketReceiveManager != null) { this.socketReceiveManager.Close(); this.socketReceiveManager = null; } // close the sockets to keep ref count consistent(socket will not be acutally closed unless ref count is 0). foreach (UdpSocket udpSocket in this.listenSockets) { udpSocket.Close(); } if (this.listenSockets != null) { this.listenSockets.Clear(); this.listenSockets = null; } } if (this.bufferManager != null) { this.bufferManager.Clear(); } if (this.channelQueue != null) { this.channelQueue.Close(); } if (this.duplicateDetector != null) { this.duplicateDetector.Dispose(); } } }
static void OnStartReceiving(object state) { UdpSocketReceiveManager thisPtr = (UdpSocketReceiveManager)state; try { if (thisPtr.IsDisposed) { return; } thisPtr.EnsureReceiving(); } catch (Exception ex) { if (!thisPtr.TryHandleException(ex)) { throw; } } }
protected override void OnClosing() { if (this.channelInstance != null) { lock (ThisLock) { if (this.channelInstance != null) { if (this.channelInstance.TransferReceiveManagerOwnership(this.socketReceiveManager, this.duplicateDetector)) { //don't clean these objects up, they now belong to the channel instance this.socketReceiveManager = null; this.duplicateDetector = null; this.bufferManager = null; } } this.channelInstance = null; } } base.OnClosing(); }
// Since ChannelListener and channel lifetimes can be different, we need a // way to transfer the socketReceiveManager and DuplicateMessageDetection // objects to the channel if the listener gets closed. If this method succeeds, then // this also indicates that the bufferManager is no longer owned by the channel listener, // so we have to clean that up also. internal bool TransferReceiveManagerOwnership(UdpSocketReceiveManager socketReceiveManager, DuplicateMessageDetector duplicateDetector) { bool success = false; if (this.State == CommunicationState.Opened) { lock (ThisLock) { if (this.State == CommunicationState.Opened) { Fx.Assert(this.ReceiveManager == null, "ReceiveManager is already set to a non-null value"); Fx.Assert(this.DuplicateDetector == null, "DuplicateDetector is already set to a non-null value"); this.ReceiveManager = socketReceiveManager; this.OwnsBufferManager = true; this.ReceiveManager.SetReceiveHandler(this); this.DuplicateDetector = duplicateDetector; success = true; } } } return(success); }