Ejemplo n.º 1
0
        public void CouldCreateBinaryConverter()
        {
            var converter = GetConverter <PreservedBuffer <byte>[]>();

            Assert.AreEqual(0, converter.Size);
            var buffers = new[] { BufferPool.PreserveMemory(10) };

            //Assert.Throws<NotImplementedException>(() =>
            //{
            converter.SizeOf(buffers, 0, 10, out var temp);
            //});
        }
Ejemplo n.º 2
0
        internal override unsafe void Free(bool finalizing)
        {
            ThrowHelper.Assert(IsDisposed);

            var array = Interlocked.Exchange(ref _array, null);

            if (array != null)
            {
                ThrowHelper.DebugAssert(TypeHelper <T> .IsReferenceOrContainsReferences);

                // Even if we are finalizing the fields are not collected, because this
                // object is reachable and hence the fields are reachable.
                if (!ExternallyOwned)
                {
                    BufferPool <T> .Return(Unsafe.As <T[]>(array), clearArray : true);
                }
            }

            var pointer = Interlocked.Exchange(ref _pointer, IntPtr.Zero);

            if (pointer != IntPtr.Zero)
            {
                // TODO Switch to mimalloc after updating to new release
                Marshal.FreeHGlobal(pointer);
                // Mem.Free((byte*) pointer);
                BuffersStatistics.ReleasedNativeMemory.InterlockedAdd(_length);
            }

            // In PM either pointer or array, never both
            if (array == null && pointer == IntPtr.Zero)
            {
                string msg = "Tried to free already freed PrivateMemory";
#if DEBUG
                ThrowHelper.ThrowInvalidOperationException(msg);
#endif
                Trace.TraceWarning(msg);
                return;
            }

            ClearFields();

            // This instance is clean now.
            // If we are finalizing then resurrect it by placing it to the pool.
            // If we are disposing then also add to the pool.
            var pooled = ObjectPool.Return(this);

            // If we were finalizing but resurrected then the next time
            // the instance is dropped the finalizer will not run,
            // therefore we must re-register.
            if (pooled && finalizing)
            {
                GC.ReRegisterForFinalize(this);
            }

            // If we cannot pool the instance and not running from finalizer
            // then the reference is dropped and finalizer could re-run.
            // In that case suppress it.
            // If not pooled and finalizing then the job is done.
            if (!pooled && !finalizing)
            {
                GC.SuppressFinalize(this);
            }
        }