private bool TryAcquireBuffer(out RioBuffer buffer) { buffer = null; int segmentId; if (!_freeBufferIds.TryPop(out segmentId)) { return(false); } buffer = _buffers[segmentId]; return(true); }
private RioBufferManager(int bufferCount, int bufferLength) { if (bufferLength <= 0) { throw new ArgumentOutOfRangeException(nameof(bufferLength)); } if (bufferCount <= 0) { throw new ArgumentOutOfRangeException(nameof(bufferCount)); } var underlyingBufferLength = (uint)(bufferLength * bufferCount); _underlyingBuffer = Kernel32.VirtualAlloc(IntPtr.Zero, underlyingBufferLength, Kernel32.Consts.MEM_COMMIT | Kernel32.Consts.MEM_RESERVE, Kernel32.Consts.PAGE_READWRITE); _bufferDescriptors = Kernel32.VirtualAlloc(IntPtr.Zero, (uint)(Marshal.SizeOf <RIO_BUF>() * bufferCount), Kernel32.Consts.MEM_COMMIT | Kernel32.Consts.MEM_RESERVE, Kernel32.Consts.PAGE_READWRITE); _bufferId = WinSock.Extensions.RegisterBuffer(_underlyingBuffer, underlyingBufferLength); if (_bufferId == WinSock.Consts.RIO_INVALID_BUFFERID) { WinSock.ThrowLastWsaError(); } _buffers = new RioBuffer[bufferCount]; var dataPointer = (byte *)_underlyingBuffer.ToPointer(); var segmentPointer = (RIO_BUF *)_bufferDescriptors.ToPointer(); for (var segmentIndex = 0; segmentIndex < bufferCount; segmentIndex++) { segmentPointer->BufferId = _bufferId; segmentPointer->Offset = segmentIndex * bufferLength; segmentPointer->Length = bufferLength; var segment = new RioBuffer(segmentIndex, dataPointer, segmentPointer, bufferLength); _buffers[segmentIndex] = segment; _freeBufferIds.Push(segment.Id); segmentPointer++; dataPointer += bufferLength; } }
public void ReleaseBuffer(RioBuffer buffer) { buffer.Reset(); _freeBufferIds.Push(buffer.Id); }