Index: ObjectPoolBase.cs =================================================================== --- ObjectPoolBase.cs (revision 2009) +++ ObjectPoolBase.cs (working copy) @@ -53,12 +53,18 @@ if (Environment.HasShutdownStarted) return; #endif + // There is a slight possibility that an object doesn't make + // it back into its segment when the entire pool is disposed. + try { + // Return this instance back to the owning queue + _owningObjectPool.CheckIn(_owningSegment, _instance); - // Object Resurrection in Action! - GC.ReRegisterForFinalize(this); - - // Return this instance back to the owning queue - _owningObjectPool.CheckIn(_owningSegment, _instance); + // Object Resurrection in Action! + GC.ReRegisterForFinalize(this); + } + catch (ObjectDisposedException ode) + { + } } /// @@ -83,8 +89,15 @@ return; _disposed = true; - _owningObjectPool.CheckIn(_owningSegment, _instance); - GC.SuppressFinalize(this); + // There is a slight possibility that an object doesn't make + // it back into its segment when the entire pool is disposed. + try { + _owningObjectPool.CheckIn(_owningSegment, _instance); + GC.SuppressFinalize(this); + } + catch (ObjectDisposedException ode) + { + } } } @@ -120,6 +133,14 @@ } /// + /// Finalizer. Clean umnaged resources only. + /// + ~ObjectPoolBase() + { + Dispose(false); + } + + /// /// Creates a new instance of the ObjectPool Base class. /// /// The object pool is composed of segments, which @@ -417,9 +438,6 @@ public void Dispose() { - if (_disposed) - return; - Dispose(true); GC.SuppressFinalize(this); @@ -427,16 +445,16 @@ protected virtual void Dispose(bool disposing) { - if (disposing) + lock (_syncRoot) { - lock (_syncRoot) - { - if (_disposed) - return; + if (_disposed) + return; - _timer.Dispose(); - _disposed = true; + _timer.Dispose(); + // Dispose managed resources on explicit call only + if (disposing) + { foreach (KeyValuePair> kvp in _segments) { try @@ -448,6 +466,8 @@ _segments.Clear(); } + + _disposed = true; } } Index: UDPBase.cs =================================================================== --- UDPBase.cs (revision 2009) +++ UDPBase.cs (working copy) @@ -168,7 +168,6 @@ public UDPBase(int port) { udpPort = port; - _bufferPool = new PacketBufferPool(new IPEndPoint(Settings.BIND_ADDR, udpPort), 64, 1); } /// @@ -179,7 +178,6 @@ { remoteEndPoint = endPoint; udpPort = 0; - _bufferPool = new PacketBufferPool(endPoint, 64, 1); } /// @@ -192,7 +190,7 @@ if (remoteEndPoint == null) { // Server mode - + _bufferPool = new PacketBufferPool(new IPEndPoint(Settings.BIND_ADDR, udpPort), 64, 1); // create and bind the socket IPEndPoint ipep = new IPEndPoint(Settings.BIND_ADDR, udpPort); udpSocket = new Socket( @@ -204,6 +202,7 @@ else { // Client mode + _bufferPool = new PacketBufferPool(remoteEndPoint, 64, 1); IPEndPoint ipep = new IPEndPoint(Settings.BIND_ADDR, udpPort); udpSocket = new Socket( AddressFamily.InterNetwork, @@ -254,6 +253,10 @@ Logger.Log("UDPBase.Stop() forced shutdown while waiting on pending operations", Helpers.LogLevel.Warning); } + + // Dispose the pool + _bufferPool.Dispose(); + _bufferPool = null; } } @@ -318,17 +321,17 @@ // aquire a reader lock rwLock.AcquireReaderLock(-1); + // get the buffer that was created in AsyncBeginReceive + // this is the received data + WrappedObject wrappedBuffer = (WrappedObject)iar.AsyncState; + UDPPacketBuffer buffer = wrappedBuffer.Instance; + //UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; + if (!shutdownFlag) { // start another receive - this keeps the server going! AsyncBeginReceive(); - // get the buffer that was created in AsyncBeginReceive - // this is the received data - WrappedObject wrappedBuffer = (WrappedObject)iar.AsyncState; - UDPPacketBuffer buffer = wrappedBuffer.Instance; - //UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; - try { // get the length of data actually read from the socket, store it with the @@ -358,8 +361,6 @@ // we're done with the socket for now, release the reader lock. rwLock.ReleaseReaderLock(); } - - wrappedBuffer.Dispose(); } else { @@ -368,6 +369,11 @@ Interlocked.Decrement(ref rwOperationCount); rwLock.ReleaseReaderLock(); } + + // Always dispose the buffer. This decreases the chances + // that an object wont back it back into its segment on + // disposal of the buffer pool. + wrappedBuffer.Dispose(); } public void AsyncBeginSend(UDPPacketBuffer buf)