예제 #1
0
        internal bool ReturnInternal(RetainableMemory <T> memory, bool clearMemory = true)
        {
            if (_disposed)
            {
                return(false);
            }

            if (memory._poolIdx != PoolIdx)
            {
                if (memory.IsDisposed)
                {
                    ThrowDisposed <RetainableMemory <T> >();
                }
                else
                {
                    ThrowNotFromPool <RetainableMemory <T> >();
                }
            }

            if (memory._isPooled)
            {
                ThrowAlreadyPooled <RetainableMemory <T> >();
            }

            // Determine with what bucket this array length is associated
            int bucket = SelectBucketIndex(memory.LengthPow2);

            // If we can tell that the buffer was allocated, drop it. Otherwise, check if we have space in the pool
            if (bucket < _buckets.Length)
            {
                // Clear the array if the user requests regardless of pooling result.
                // If not pooled then it should be RM.DisposeFinalize-d and destruction
                // is not always GC.
                if (clearMemory || IsRentAlwaysClean || _typeHasReferences)
                {
                    if (!memory.SkipCleaning)
                    {
                        memory.GetSpan().Clear();
                    }
                }

                memory.SkipCleaning = false;

                // Return the buffer to its bucket.  In the future, we might consider having Return return false
                // instead of dropping a bucket, in which case we could try to return to a lower-sized bucket,
                // just as how in Rent we allow renting from a higher-sized bucket.
                _buckets[bucket].Return(memory);
            }

            // Log that the buffer was returned
            var log = RetainableMemoryPoolEventSource.Log;

            if (log.IsEnabled())
            {
                log.BufferReturned(memory.GetHashCode(), memory.Length, Id);
            }

            return(memory._isPooled);
        }
예제 #2
0
        internal bool ReturnInternal(RetainableMemory <T> memory, bool clearMemory = true)
        {
            if (_disposed)
            {
                return(false);
            }

            if (!memory.IsDisposed)
            {
                ThrowHelper.ThrowInvalidOperationException("Memory must be disposed before returning to RMP.");
            }

            if (memory.PoolIndex != PoolIdx)
            {
                ThrowNotFromPool <RetainableMemory <T> >();
            }

            // Determine with what bucket this buffer length is associated
            var bucketIndex = SelectBucketIndex(memory.LengthPow2);

            var pooled = false;

            // If we can tell that the buffer was allocated, drop it. Otherwise, check if we have space in the pool
            if (bucketIndex < _buckets.Length)
            {
                var bucket = _buckets[bucketIndex];
                if (memory.LengthPow2 != bucket.BufferLength)
                {
                    ThrowNotFromPool <RetainableMemory <T> >();
                }

#pragma warning disable 618
                // Clear the memory if the user requests regardless of pooling result.
                // If not pooled then it should be RM.DisposeFinalize-d and destruction
                // is not always GC.
                if ((clearMemory || IsRentAlwaysClean || _typeHasReferences) && !memory.SkipCleaning)
                {
                    memory.GetSpan().Clear();
                }
                memory.SkipCleaning = false;
#pragma warning restore 618

                pooled = bucket.Return(memory);
            }

            // Log that the buffer was returned
            var log = RetainableMemoryPoolEventSource.Log;
            if (log.IsEnabled())
            {
                log.BufferReturned(memory.GetHashCode(), memory.Length, Id);
            }

            return(pooled);
        }