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