Beispiel #1
0
        protected override void Dispose(bool disposing)
        {
            if (IsDisposed)
            {
                MemoryPoolThrowHelper.ThrowInvalidOperationException_DoubleDispose();
            }

            bool allBlocksReturned = false;

            try {
                lock (_syncObj) {
                    IsDisposed        = true;
                    allBlocksReturned = _blocks.Count == 0;
                    if (!allBlocksReturned && !_allowLateReturn)
                    {
                        MemoryPoolThrowHelper.ThrowInvalidOperationException_DisposingPoolWithActiveBlocks(_totalBlocks - _blocks.Count, _totalBlocks, _blocks.ToArray());
                    }

                    if (_blockAccessExceptions.Any())
                    {
                        throw CreateAccessExceptions();
                    }
                }
            } finally {
                if (allBlocksReturned)
                {
                    SetAllBlocksReturned();
                }
            }
        }
        protected override void Dispose(bool disposing)
        {
            try {
                lock (_syncObj) {
                    if (Volatile.Read(ref _pinCount) > 0)
                    {
                        MemoryPoolThrowHelper.ThrowInvalidOperationException_ReturningPinnedBlock(this);
                    }

                    if (_isDisposed)
                    {
                        MemoryPoolThrowHelper.ThrowInvalidOperationException_BlockDoubleDispose(this);
                    }

                    _memoryOwner.Dispose();

                    _pool.Return(this);

                    _isDisposed = true;
                }
            } catch (Exception exception) {
                _pool.ReportException(exception);
                throw;
            }
        }
        public override MemoryHandle Pin(int byteOffset = 0)
        {
            try {
                lock (_syncObj) {
                    if (_isDisposed)
                    {
                        MemoryPoolThrowHelper.ThrowObjectDisposedException(MemoryPoolThrowHelper.ExceptionArgument.MemoryPoolBlock);
                    }

                    if (_pool.IsDisposed)
                    {
                        MemoryPoolThrowHelper.ThrowInvalidOperationException_BlockIsBackedByDisposedSlab(this);
                    }

                    if (byteOffset < 0 || byteOffset > _memory.Length)
                    {
                        MemoryPoolThrowHelper.ThrowArgumentOutOfRangeException(_memory.Length, byteOffset);
                    }

                    _pinCount++;

                    _memoryHandle = _memoryHandle ?? _memory.Pin();

                    unsafe {
                        return(new MemoryHandle(((IntPtr)_memoryHandle.Value.Pointer + byteOffset).ToPointer(), default, this));
Beispiel #4
0
        public async Task WhenAllBlocksReturnedAsync(TimeSpan timeout)
        {
            var task = await Task.WhenAny(_allBlocksReturned.Task, Task.Delay(timeout));

            if (task != _allBlocksReturned.Task)
            {
                MemoryPoolThrowHelper.ThrowInvalidOperationException_BlocksWereNotReturnedInTime(_totalBlocks - _blocks.Count, _totalBlocks, _blocks.ToArray());
            }

            await task;
        }
Beispiel #5
0
        public override IMemoryOwner <byte> Rent(int size = AnySize)
        {
            if (size > _blockSize)
            {
                MemoryPoolThrowHelper.ThrowArgumentOutOfRangeException_BufferRequestTooLarge(_blockSize);
            }

            var block = Lease();

            return(block);
        }
Beispiel #6
0
        public override IMemoryOwner <byte> Rent(int size = AnySize)
        {
            lock (_syncObj) {
                if (IsDisposed)
                {
                    MemoryPoolThrowHelper.ThrowObjectDisposedException(MemoryPoolThrowHelper.ExceptionArgument.MemoryPool);
                }

                var diagnosticPoolBlock = new DiagnosticPoolBlock(this, _pool.Rent(size));
                if (_rentTracking)
                {
                    diagnosticPoolBlock.Track();
                }
                _totalBlocks++;
                _blocks.Add(diagnosticPoolBlock);
                return(diagnosticPoolBlock);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Called to take a block from the pool.
        /// </summary>
        /// <returns>The block that is reserved for the called. It must be passed to Return when it is no longer being used.</returns>
        private MemoryPoolBlock Lease()
        {
            if (_isDisposed)
            {
                MemoryPoolThrowHelper.ThrowObjectDisposedException(MemoryPoolThrowHelper.ExceptionArgument.MemoryPool);
            }

            if (_blocks.TryDequeue(out MemoryPoolBlock block))
            {
                // block successfully taken from the stack - return it

                block.Lease();
                return(block);
            }
            // no blocks available - grow the pool
            block = AllocateSlab();
            block.Lease();
            return(block);
        }
        public override Span <byte> GetSpan()
        {
            try {
                lock (_syncObj) {
                    if (_isDisposed)
                    {
                        MemoryPoolThrowHelper.ThrowObjectDisposedException(MemoryPoolThrowHelper.ExceptionArgument.MemoryPoolBlock);
                    }

                    if (_pool.IsDisposed)
                    {
                        MemoryPoolThrowHelper.ThrowInvalidOperationException_BlockIsBackedByDisposedSlab(this);
                    }

                    return(_memory.Span);
                }
            } catch (Exception exception) {
                _pool.ReportException(exception);
                throw;
            }
        }
Beispiel #9
0
        internal void Return(DiagnosticPoolBlock block)
        {
            bool returnedAllBlocks;

            lock (_syncObj) {
                _blocks.Remove(block);
                returnedAllBlocks = _blocks.Count == 0;
            }

            if (IsDisposed)
            {
                if (!_allowLateReturn)
                {
                    MemoryPoolThrowHelper.ThrowInvalidOperationException_BlockReturnedToDisposedPool(block);
                }

                if (returnedAllBlocks)
                {
                    SetAllBlocksReturned();
                }
            }
        }