예제 #1
0
        public static void NoRelease_AfterDispose()
        {
            OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42);

            block.Release();
            block.Dispose();
            Assert.Throws <ObjectDisposedException>(() => block.Release());
        }
예제 #2
0
        static void MemoryHandleDoubleFree(OwnedMemory <byte> buffer)
        {
            var memory = buffer.Memory;
            var handle = memory.Retain(pin: true);

            buffer.Retain();
            handle.Dispose();
            handle.Dispose();
            Assert.True(buffer.Release());
            Assert.False(buffer.Release());
        }
예제 #3
0
        static void BufferLifetimeBasics(OwnedMemory <byte> buffer)
        {
            Memory <byte> copyStoredForLater;

            try
            {
                Memory <byte> memory = buffer.Memory;
                Memory <byte> slice  = memory.Slice(10);
                copyStoredForLater = slice;
                var handle = slice.Retain();
                try
                {
                    Assert.Throws <InvalidOperationException>(() =>
                    { // memory is reserved; premature dispose check fires
                        buffer.Dispose();
                    });
                }
                finally
                {
                    handle.Dispose(); // release reservation
                }
                buffer.Release();
            }
            finally
            {
                buffer.Dispose(); // can finish dispose with no exception
            }
            Assert.ThrowsAny <ObjectDisposedException>(() =>
            {
                // memory is disposed; cannot use copy stored for later
                var span = copyStoredForLater.Span;
            });

            Assert.True(buffer.IsDisposed);
        }
예제 #4
0
 static void OverRelease(OwnedMemory <byte> buffer)
 {
     Assert.ThrowsAny <InvalidOperationException>(() =>
     {
         buffer.Release();
     });
 }
예제 #5
0
        static void Dispose(OwnedMemory <byte> buffer)
        {
            var length = buffer.Length;

            buffer.Release();

            buffer.Dispose();
            Assert.True(buffer.IsDisposed);

            Assert.ThrowsAny <ObjectDisposedException>(() =>
            {
                var ignore = buffer.Span;
            });

            Assert.ThrowsAny <ObjectDisposedException>(() =>
            {
                buffer.Span.Slice(0, length);
            });

            Assert.ThrowsAny <ObjectDisposedException>(() =>
            {
                buffer.Pin();
            });

            Assert.ThrowsAny <ObjectDisposedException>(() =>
            {
                var rwBuffer = buffer.Memory;
            });

            Assert.ThrowsAny <ObjectDisposedException>((Action)(() =>
            {
                ReadOnlyMemory <byte> roBuffer = buffer.Memory;
            }));
        }
예제 #6
0
        public static void ExtraDisposesAreIgnored()
        {
            OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42);

            block.Release();
            block.Dispose();
            block.Dispose();
        }
예제 #7
0
 public static void RentWithDefaultSize()
 {
     using (OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(minBufferSize: -1))
     {
         Assert.True(block.Length >= 1);
         block.Release();
     }
 }
예제 #8
0
        public static void IsDisposedWhenReleased()
        {
            OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42);

            block.Release();

            Assert.True(block.IsDisposed);
        }
예제 #9
0
        public static void NoTryGetArrayAfterDispose()
        {
            OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42);

            Memory <int> memory = block.Memory;

            block.Release();
            block.Dispose();
            Assert.Throws <ObjectDisposedException>(() => MemoryMarshal.TryGetArray(memory, out ArraySegment <int> arraySegment));
        }
예제 #10
0
        public void Dispose()
        {
            Debug.Assert(_buffer.HasOutstandingReferences);

            _buffer.Release();

            if (!_buffer.HasOutstandingReferences)
            {
                _buffer.Dispose();
            }
        }
예제 #11
0
        public void Dispose()
        {
            Debug.Assert(_buffer.ReferenceCount >= 1);

            _buffer.Release();

            if (_buffer.ReferenceCount == 0)
            {
                _buffer.Dispose();
            }
        }
예제 #12
0
        public static void DisposingTheSharedPoolIsANop()
        {
            MemoryPool <int> mp = MemoryPool <int> .Shared;

            mp.Dispose();
            mp.Dispose();
            using (OwnedMemory <int> block = mp.Rent(10))
            {
                Assert.True(block.Length >= 10);
                block.Release();
            }
        }
예제 #13
0
        public static void RefCounting()
        {
            using (OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42))
            {
                block.Retain();
                block.Retain();
                block.Retain();

                bool moreToGo;
                moreToGo = block.Release();
                Assert.True(moreToGo);

                moreToGo = block.Release();
                Assert.True(moreToGo);

                moreToGo = block.Release();
                Assert.False(moreToGo);

                Assert.Throws <InvalidOperationException>(() => block.Release());
            }
        }
예제 #14
0
            public override bool Release()
            {
                _pool.CheckDisposed();
                _ownedMemory.Release();

                int newRefCount = Interlocked.Decrement(ref _referenceCount);

                if (newRefCount < 0)
                {
                    throw new InvalidOperationException();
                }

                if (newRefCount == 0)
                {
                    _returned = true;
                    return(false);
                }
                return(true);
            }
예제 #15
0
 public static void MemoryPoolTryGetArray()
 {
     using (OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42))
     {
         Memory <int> memory  = block.Memory;
         bool         success = MemoryMarshal.TryGetArray(memory, out ArraySegment <int> arraySegment);
         Assert.True(success);
         Assert.Equal(block.Length, arraySegment.Count);
         unsafe
         {
             void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(block.Span));
             fixed(int *pArray = arraySegment.Array)
             {
                 Assert.Equal((IntPtr)pSpan, (IntPtr)pArray);
             }
         }
         block.Release();
     }
 }
예제 #16
0
        public static void MemoryPoolPin(int byteOffset)
        {
            MemoryPool <int> pool = MemoryPool <int> .Shared;

            using (OwnedMemory <int> block = pool.Rent(10))
            {
                Span <int> sp = block.Span;
                Assert.Equal(block.Length, sp.Length);
                using (MemoryHandle newMemoryHandle = block.Pin(byteOffset: byteOffset))
                {
                    unsafe
                    {
                        void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp));
                        Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer) - byteOffset);
                    }
                }
                block.Release();
            }
        }
예제 #17
0
        public void ReleasedBlockWorks()
        {
            using (var pool = new MemoryPool())
            {
                var block1 = pool.Rent(1);
                block1.Retain();
                block1.Release();

                OwnedMemory <byte> block2 = null;

                // Lease-return until we get same block
                while (block1 != block2)
                {
                    block2 = pool.Rent(1);
                    block2.Retain();
                    block2.Release();
                }

                Assert.True(block2.Span.Length > 0);
            }
        }
예제 #18
0
 public void ResetMemory()
 {
     _ownedMemory.Release();
     _ownedMemory = null;
     _memory      = default;
 }
예제 #19
0
 protected override void Dispose(bool disposing)
 {
     _rentedBuffer.Release();
     //_rentedBuffer.Dispose();
     base.Dispose(disposing);
 }
예제 #20
0
        public JsonObject Parse(ReadOnlySpan <byte> utf8Json, MemoryPool <byte> pool = null)
        {
            _pool = pool;
            if (_pool == null)
            {
                _pool = MemoryPool <byte> .Shared;
            }
            _scratchManager = _pool.Rent(utf8Json.Length * 4);
            _scratchMemory  = _scratchManager.Memory;

            int dbLength = _scratchMemory.Length / 2;

            _db    = _scratchMemory.Slice(0, dbLength);
            _stack = new TwoStacks(_scratchMemory.Slice(dbLength));

            _values            = utf8Json;
            _insideObject      = 0;
            _insideArray       = 0;
            _tokenType         = 0;
            _valuesIndex       = 0;
            _dbIndex           = 0;
            _jsonStartIsObject = false;

            SkipWhitespace();

            _jsonStartIsObject = _values[_valuesIndex] == '{';

            int arrayItemsCount        = 0;
            int numberOfRowsForMembers = 0;

            while (Read())
            {
                var tokenType = _tokenType;
                switch (tokenType)
                {
                case JsonTokenType.ObjectStart:
                    AppendDbRow(JsonObject.JsonValueType.Object, _valuesIndex);
                    while (!_stack.TryPushObject(numberOfRowsForMembers))
                    {
                        ResizeDb();
                    }
                    numberOfRowsForMembers = 0;
                    break;

                case JsonTokenType.ObjectEnd:
                    WriteMachineEndian(_db.Span.Slice(FindLocation(_stack.ObjectStackCount - 1, true)), ref numberOfRowsForMembers);
                    numberOfRowsForMembers += _stack.PopObject();
                    break;

                case JsonTokenType.ArrayStart:
                    AppendDbRow(JsonObject.JsonValueType.Array, _valuesIndex);
                    while (!_stack.TryPushArray(arrayItemsCount))
                    {
                        ResizeDb();
                    }
                    arrayItemsCount = 0;
                    break;

                case JsonTokenType.ArrayEnd:
                    WriteMachineEndian(_db.Span.Slice(FindLocation(_stack.ArrayStackCount - 1, false)), ref arrayItemsCount);
                    arrayItemsCount = _stack.PopArray();
                    break;

                case JsonTokenType.Property:
                    ParsePropertyName();
                    ParseValue();
                    numberOfRowsForMembers++;
                    numberOfRowsForMembers++;
                    break;

                case JsonTokenType.Value:
                    ParseValue();
                    arrayItemsCount++;
                    numberOfRowsForMembers++;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var result = new JsonObject(_values, _db.Slice(0, _dbIndex).Span, _pool, _scratchManager);

            _scratchManager.Release();
            _scratchManager = null;
            return(result);
        }
예제 #21
0
        public static void IsRetainedWhenReturned()
        {
            OwnedMemory <int> block = MemoryPool <int> .Shared.Rent(42);

            Assert.False(block.Release());
        }
예제 #22
0
 public void ResetMemory()
 {
     _owned.Release();
     _owned = null;
 }