public void ArrayMemoryLifetime() { Memory <byte> copyStoredForLater; var owner = new OwnedArray <byte>(1024); try { Memory <byte> memory = owner.Memory; Memory <byte> memorySlice = memory.Slice(10); copyStoredForLater = memorySlice; var r = memorySlice.Reserve(); try { // increments the "outstanding span" refcount Assert.Throws <InvalidOperationException>(() => { // memory is reserved; cannot dispose owner.Dispose(); }); Assert.Throws <ObjectDisposedException>(() => { Span <byte> span = memorySlice.Span; span[0] = 255; }); } finally { Assert.Throws <ObjectDisposedException>(() => { r.Dispose(); // releases the refcount }); } } finally { Assert.Throws <InvalidOperationException>(() => { owner.Dispose(); }); } Assert.Throws <ObjectDisposedException>(() => { // manager is disposed var span = copyStoredForLater.Span; }); }
public void Create_WorksWithOwnedMemory() { var memory = new OwnedArray <byte>(new byte[] { 1, 2, 3, 4, 5 }); var readableBuffer = new ReadOnlyBuffer <byte>(memory, 2, 3); Assert.Equal(new byte[] { 3, 4, 5 }, readableBuffer.ToArray()); }
public void ArrayMemoryLifetime() { var array = new byte[1024]; OwnedArray <byte> owned = array; TestLifetime(owned); }
public void RacyAccess() { for (int k = 0; k < 1000; k++) { var owners = new IMemoryOwner <byte> [128]; var memories = new Memory <byte> [owners.Length]; var reserves = new MemoryHandle[owners.Length]; var disposeSuccesses = new bool[owners.Length]; var reserveSuccesses = new bool[owners.Length]; for (int i = 0; i < owners.Length; i++) { var array = new byte[1024]; owners[i] = new OwnedArray <byte>(array); memories[i] = owners[i].Memory; } var dispose_task = Task.Run(() => { for (int i = 0; i < owners.Length; i++) { try { owners[i].Dispose(); disposeSuccesses[i] = true; } catch (InvalidOperationException) { disposeSuccesses[i] = false; } } }); var reserve_task = Task.Run(() => { for (int i = owners.Length - 1; i >= 0; i--) { try { reserves[i] = memories[i].Pin(); reserveSuccesses[i] = true; } catch (ObjectDisposedException) { reserveSuccesses[i] = false; } } }); Task.WaitAll(reserve_task, dispose_task); for (int i = 0; i < owners.Length; i++) { Assert.False(disposeSuccesses[i] && reserveSuccesses[i]); } } }
/// <summary> /// Create a <see cref="ReadableBuffer"/> over an array. /// </summary> public static ReadableBuffer Create(byte[] data) { if (data == null) { PipelinesThrowHelper.ThrowArgumentNullException(ExceptionArgument.data); } OwnedMemory <byte> buffer = new OwnedArray <byte>(data); return(CreateInternal(buffer, 0, data.Length)); }
WeakReference LeakHandle() { // Creates an object that is both Pinned with a MemoryHandle, // and has a weak reference. var array = new byte[1024]; OwnedArray <byte> owned = array; var memory = owned.Buffer; memory.Pin(); return(new WeakReference(array)); }
public HttpResponse(int size) { var headersArray = ArrayPool <byte> .Shared.Rent(size / 2); _headersMemory = new OwnedArray <byte>(headersArray); _headers = new ReadWriteBytes(_headersMemory.Memory); var bodyArray = ArrayPool <byte> .Shared.Rent(size / 2); _bodyMemory = new OwnedArray <byte>(bodyArray); _body = new ReadWriteBytes(_bodyMemory.Memory); }
public void PinAddReferenceReleaseTest() { var array = new byte[1024]; OwnedArray <byte> owned = array; var memory = owned.Buffer; Assert.False(owned.IsRetained); var h = memory.Pin(); Assert.True(owned.IsRetained); h.Dispose(); Assert.False(owned.IsRetained); }
protected override DisposableReservation Reserve(ref ReadOnlyMemory <byte> memory) { if (memory.Length < Length) { var copy = memory.Span.ToArray(); OwnedArray <byte> newOwned = copy; memory = newOwned.Memory; return(memory.Reserve()); } else { return(base.Reserve(ref memory)); } }
protected virtual void ProcessRequest(TcpConnection socket) { Log.LogVerbose("Processing Request"); var requestBuffer = s_pool.Rent(RequestBufferSize); var arrayMemory = new OwnedArray <byte>(requestBuffer); var requestByteCount = socket.Receive(requestBuffer); if (requestByteCount == 0) { socket.Close(); return; } var requestMemory = arrayMemory.Memory.Slice(0, requestByteCount); var requestBytes = new ReadOnlyBytes(requestMemory); var request = HttpRequest.Parse(requestBytes); Log.LogRequest(request); using (var response = new HttpResponse(1024)) { WriteResponse(request, response); s_pool.Return(requestBuffer); Position position = Position.First; while (response.Headers.TryGet(ref position, out var headersSegment, true)) { socket.Send(headersSegment.Slice(0, response.HeadersLength)); } position = Position.First; while (response.Body.TryGet(ref position, out var bodySegment)) { socket.Send(bodySegment.Slice(0, response.BodyLength)); } socket.Close(); } if (Log.IsVerbose) { Log.LogMessage(Log.Level.Verbose, "Request Processed and Response Sent", DateTime.UtcNow.Ticks); } }
public void MemoryHandleDoubleFree() { var array = new byte[1024]; OwnedArray <byte> owned = array; var memory = owned.Buffer; var h = memory.Pin(); Assert.True(owned.IsRetained); owned.Retain(); Assert.True(owned.IsRetained); h.Dispose(); Assert.True(owned.IsRetained); h.Dispose(); Assert.True(owned.IsRetained); owned.Release(); Assert.False(owned.IsRetained); }
public void SimpleTestS() { { var array = new byte[1024]; OwnedArray <byte> owned = array; var span = owned.AsSpan(); span[10] = 10; Assert.Equal(10, array[10]); var memory = owned.Buffer; var toArrayResult = memory.ToArray(); Assert.Equal(owned.Length, array.Length); Assert.Equal(10, toArrayResult[10]); Span <byte> copy = new byte[20]; memory.Slice(10, 20).CopyTo(copy); Assert.Equal(10, copy[0]); } }
public static ReadableBuffer CreateBuffer(params byte[][] inputs) { if (inputs == null || inputs.Length == 0) { throw new InvalidOperationException(); } var i = 0; BufferSegment last = null; BufferSegment first = null; do { var s = inputs[i]; var length = s.Length; var dataOffset = length; var chars = new byte[length * 8]; for (int j = 0; j < length; j++) { chars[dataOffset + j] = s[j]; } // Create a segment that has offset relative to the OwnedMemory and OwnedMemory itself has offset relative to array var ownedBuffer = new OwnedArray <byte>(chars); var current = new BufferSegment(); current.SetMemory(ownedBuffer, length, length * 2); if (first == null) { first = current; last = current; } else { last.SetNext(current); last = current; } i++; } while (i < inputs.Length); return(new ReadableBuffer(new ReadCursor(first, first.Start), new ReadCursor(last, last.Start + last.ReadableBytes))); }
public ReadableBuffer CreateBuffer(params string[] inputs) { if (inputs == null || !inputs.Any()) { throw new InvalidOperationException(); } var i = 0; BufferSegment last = null; BufferSegment first = null; do { var s = inputs[i]; var length = s.Length; var memoryOffset = length; var dataOffset = length * 2; var chars = new byte[length * 8]; for (int j = 0; j < length; j++) { chars[dataOffset + j] = (byte)s[j]; } // Create a segment that has offset relative to the OwnedMemory and OwnedMemory itself has offset relative to array var ownedMemory = new OwnedArray <byte>(new ArraySegment <byte>(chars, memoryOffset, length * 3)); var current = new BufferSegment(ownedMemory, length, length * 2); if (first == null) { first = current; last = current; } else { last.Next = current; last = current; } i++; } while (i < inputs.Length); return(new ReadableBuffer(new ReadCursor(first, first.Start), new ReadCursor(last, last.Start + last.ReadableBytes))); }
public static ReadOnlySequence <T> CreateBuffer <T>(params T[][] inputs) where T : struct { if (inputs == null || inputs.Length == 0) { throw new InvalidOperationException(); } BufferSegment <T> last = null; BufferSegment <T> first = null; for (int i = 0; i < inputs.Length; i++) { T[] source = inputs[i]; int length = source.Length; int dataOffset = length; // Shift the incoming data for testing T[] chars = new T[length * 8]; for (int j = 0; j < length; j++) { chars[dataOffset + j] = source[j]; } // Create a segment that has offset relative to the OwnedMemory and OwnedMemory itself has offset relative to array var ownedBuffer = new OwnedArray <T>(chars); var current = new BufferSegment <T>(); current.SetMemory(ownedBuffer, length, length * 2); if (first == null) { first = current; last = current; } else { last.SetNext(current); last = current; } } return(new ReadOnlySequence <T>(first, 0, last, last.Length)); }
public void CanUseOwnedBufferBasedReadableBuffers() { var data = Encoding.ASCII.GetBytes("***abc|def|ghijk****"); // note sthe padding here - verifying that it is omitted correctly OwnedMemory <byte> owned = new OwnedArray <byte>(data); var buffer = ReadableBuffer.Create(owned, 3, data.Length - 7); Assert.Equal(13, buffer.Length); var split = buffer.Split((byte)'|'); Assert.Equal(3, split.Count()); using (var iter = split.GetEnumerator()) { Assert.True(iter.MoveNext()); var current = iter.Current; Assert.Equal("abc", current.GetAsciiString()); using (var preserved = iter.Current.Preserve()) { Assert.Equal("abc", preserved.Buffer.GetAsciiString()); } Assert.True(iter.MoveNext()); current = iter.Current; Assert.Equal("def", current.GetAsciiString()); using (var preserved = iter.Current.Preserve()) { Assert.Equal("def", preserved.Buffer.GetAsciiString()); } Assert.True(iter.MoveNext()); current = iter.Current; Assert.Equal("ghijk", current.GetAsciiString()); using (var preserved = iter.Current.Preserve()) { Assert.Equal("ghijk", preserved.Buffer.GetAsciiString()); } Assert.False(iter.MoveNext()); } }
public static ReadOnlySequence <T> CreateSplitBuffer <T>(T[] buffer, int minSize, int maxSize) where T : struct { if (buffer == null || buffer.Length == 0 || minSize <= 0 || maxSize <= 0 || minSize > maxSize) { throw new InvalidOperationException(); } Random r = new Random(0xFEED); BufferSegment <T> last = null; BufferSegment <T> first = null; var ownedBuffer = new OwnedArray <T>(buffer); int remaining = buffer.Length; int position = 0; while (remaining > 0) { int take = Math.Min(r.Next(minSize, maxSize), remaining); BufferSegment <T> current = new BufferSegment <T>(); current.SetMemory(ownedBuffer, position, position + take); if (first == null) { first = current; last = current; } else { last.SetNext(current); last = current; } remaining -= take; position += take; } return(new ReadOnlySequence <T>(first, 0, last, last.Length)); }
/// <summary> /// Create a <see cref="ReadableBuffer"/> over an array. /// </summary> public static ReadableBuffer Create(byte[] data, int offset, int length) { if (data == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.data); } if (offset < 0) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.offset); } if (length < 0 || (offset + length) > data.Length) { ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length); } var buffer = new OwnedArray <byte>(data); var segment = new BufferSegment(buffer); segment.Start = offset; segment.End = offset + length; return(new ReadableBuffer(new ReadCursor(segment, offset), new ReadCursor(segment, offset + length))); }
public void ArrayMemoryLifetime() { var owner = new OwnedArray <byte>(1024); TestLifetime(owner); }