private ObjectPoolSegment <T> CreateSegment(bool allowSegmentToBeCleanedUp)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("ObjectPoolBase");
            }


            // This method is called inside a lock, so no interlocked stuff required.
            int segmentToAdd = _activeSegment;

            _activeSegment++;

            Queue <T> buffers = new Queue <T>();

            for (int i = 1; i <= this._itemsPerSegment; i++)
            {
                T obj = GetObjectInstance();
                buffers.Enqueue(obj);
            }

            // certain segments we don't want to ever be cleaned up (the initial segments)
            DateTime cleanupTime          = (allowSegmentToBeCleanedUp) ? DateTime.Now.Add(this._minimumAgeToCleanup) : DateTime.MaxValue;
            ObjectPoolSegment <T> segment = new ObjectPoolSegment <T>(segmentToAdd, buffers, cleanupTime);

            return(segment);
        }
 /// <summary>
 /// Checks in an instance of T owned by the object pool. This method is only intended to be called
 /// by the <c>WrappedObject</c> class.
 /// </summary>
 /// <param name="owningSegment">The segment from which the instance is checked out.</param>
 /// <param name="instance">The instance of <c>T</c> to check back into the segment.</param>
 internal void CheckIn(ObjectPoolSegment <T> owningSegment, T instance)
 {
     lock (_syncRoot)
     {
         owningSegment.CheckInObject(instance);
     }
 }
        protected void Initialize(int itemsPerSegment, int minimumSegmentCount, bool gcOnPoolGrowth, int cleanupFrequenceMS)
        {
            _itemsPerSegment     = itemsPerSegment;
            _minimumSegmentCount = minimumSegmentCount;
            _gc = gcOnPoolGrowth;

            // force garbage collection to make sure these new long lived objects
            // cause as little fragmentation as possible
            if (_gc)
            {
                System.GC.Collect();
            }

            lock (_syncRoot)
            {
                while (_segments.Count < this.MinimumSegmentCount)
                {
                    ObjectPoolSegment <T> segment = CreateSegment(false);
                    _segments.Add(segment.SegmentNumber, segment);
                }
            }

            // This forces a compact, to make sure our objects fill in any holes in the heap.
            if (_gc)
            {
                System.GC.Collect();
            }

            _timer = new Timer(CleanupThreadCallback, null, cleanupFrequenceMS, cleanupFrequenceMS);
        }
        /// <summary>
        /// Checks an instance of <c>T</c> from the pool. If the pool is not sufficient to
        /// allow the checkout, a new segment is created.
        /// </summary>
        /// <returns>A <c>WrappedObject</c> around the instance of <c>T</c>. To check
        /// the instance back into the segment, be sureto dispose the WrappedObject
        /// when finished. </returns>
        public WrappedObject <T> CheckOut()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("ObjectPoolBase");
            }

            // It's key that this CheckOut always, always, uses a pooled object
            // from the oldest available segment. This will help keep the "newer"
            // segments from being used - which in turn, makes them eligible
            // for deletion.


            lock (_syncRoot)
            {
                ObjectPoolSegment <T> targetSegment = null;

                // find the oldest segment that has items available for checkout
                for (int i = 0; i < _activeSegment; i++)
                {
                    ObjectPoolSegment <T> segment;
                    if (_segments.TryGetValue(i, out segment) == true)
                    {
                        if (segment.AvailableItems > 0)
                        {
                            targetSegment = segment;
                            break;
                        }
                    }
                }

                if (targetSegment == null)
                {
                    // We couldn't find a sigment that had any available space in it,
                    // so it's time to create a new segment.

                    // Before creating the segment, do a GC to make sure the heap
                    // is compacted.
                    if (_gc)
                    {
                        GC.Collect();
                    }

                    targetSegment = CreateSegment(true);

                    if (_gc)
                    {
                        GC.Collect();
                    }

                    _segments.Add(targetSegment.SegmentNumber, targetSegment);
                }

                WrappedObject <T> obj = new WrappedObject <T>(this, targetSegment, targetSegment.CheckOutObject());
                return(obj);
            }
        }
 internal WrappedObject(ObjectPoolBase <T> owningPool, ObjectPoolSegment <T> ownerSegment, T activeInstance)
 {
     _owningObjectPool = owningPool;
     _owningSegment    = ownerSegment;
     _instance         = activeInstance;
 }