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));
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; } }
public async Task WhenAllBlocksReturnedAsync(TimeSpan timeout) { var task = await Task.WhenAny(_allBlocksRetuned.Task, Task.Delay(timeout)); if (task != _allBlocksRetuned.Task) { MemoryPoolThrowHelper.ThrowInvalidOperationException_BlocksWereNotReturnedInTime(_totalBlocks - _blocks.Count, _totalBlocks, _blocks.ToArray()); } await task; }
public override IMemoryOwner <byte> Rent(int size = AnySize) { if (size > _blockSize) { MemoryPoolThrowHelper.ThrowArgumentOutOfRangeException_BufferRequestTooLarge(_blockSize); } var block = Lease(); return(block); }
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); } }
/// <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); }
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(); } } }