Esempio n. 1
0
        public void MultipleReleaseAtDifferentThreadTest()
        {
            ThreadLocalPool <HandledObject> pool = NewPool(1024);
            HandledObject obj = pool.Take();

            Thread thread = new Thread(() =>
            {
                obj.Release();
            });

            thread.Start();
            thread.Join();

            ExceptionDispatchInfo exceptionDispatchInfo = null;
            Thread thread2 = new Thread(() =>
            {
                try
                {
                    obj.Release();
                }
                catch (Exception ex)
                {
                    Interlocked.Exchange(ref exceptionDispatchInfo, ExceptionDispatchInfo.Capture(ex));
                }
            });

            thread2.Start();
            thread2.Join();
            var exception = Assert.ThrowsAny <InvalidOperationException>(() => Volatile.Read(ref exceptionDispatchInfo)?.Throw());

            Assert.True(exception != null);
        }
Esempio n. 2
0
 PooledByteBuffer(ThreadLocalPool.Handle returnHandle, IByteBufferAllocator allocator, byte[] pooledArray, int maxCapacity)
     : base(allocator, pooledArray, 0, 0, maxCapacity)
 {
     this.length = pooledArray.Length;
     this.returnHandle = returnHandle;
     this.pooledArray = pooledArray;
 }
Esempio n. 3
0
        public void MultipleReleaseTest()
        {
            ThreadLocalPool <HandledObject> pool = NewPool(1024);
            HandledObject obj = pool.Take();

            obj.Release();
            var exception = Assert.ThrowsAny <InvalidOperationException>(() => obj.Release());

            Assert.True(exception != null);
        }
        public PooledByteBufferAllocator(int maxPooledBufSize, int maxLocalPoolSize)
        {
            Contract.Requires(maxLocalPoolSize > maxPooledBufSize);

            this.MaxPooledBufSize = maxPooledBufSize;
            this.pool             = new ThreadLocalPool <PooledByteBuffer>(
                handle => new PooledByteBuffer(handle, this, maxPooledBufSize, int.MaxValue),
                maxLocalPoolSize / maxPooledBufSize,
                false); // todo: prepare
        }
        public PooledByteBufferAllocator(int maxPooledBufSize, int maxLocalPoolSize)
        {
            Contract.Requires(maxLocalPoolSize > maxPooledBufSize);

            this.MaxPooledBufSize = maxPooledBufSize;
            this.pool = new ThreadLocalPool<PooledByteBuffer>(
                handle => new PooledByteBuffer(handle, this, maxPooledBufSize, int.MaxValue),
                maxLocalPoolSize / maxPooledBufSize,
                false);
        }
Esempio n. 6
0
        public void ReleaseDisableTest()
        {
            ThreadLocalPool <HandledObject> pool = NewPool(-1);
            HandledObject obj = pool.Take();

            obj.Release();
            HandledObject obj2 = pool.Take();

            Assert.NotSame(obj, obj2);
            obj2.Release();
        }
Esempio n. 7
0
        private static ThreadLocalPool <AbstractPoolObject> Register <T>(Type type) where T : AbstractPoolObject
        {
            var pool = new ThreadLocalPool <AbstractPoolObject>(handle =>
            {
                var t            = Activator.CreateInstance(type) as T;
                t.RecyclerHandle = handle;
                return(t);
            });

            recycler.TryAdd(type, pool);
            return(pool);
        }
Esempio n. 8
0
 internal Stack(ThreadLocalPool parent, Thread thread, int maxCapacity, int maxSharedCapacityFactor,
                int interval, int maxDelayedQueues, int delayedQueueInterval)
 {
     _parent                  = parent;
     _threadRef               = new WeakReference <Thread>(thread);
     _maxCapacity             = maxCapacity;
     _availableSharedCapacity = new StrongBox <int>(Math.Max(maxCapacity / maxSharedCapacityFactor, LinkCapacity));
     _elements                = new DefaultHandle[Math.Min(DefaultInitialCapacity, maxCapacity)];
     _interval                = interval;
     _delayedQueueInterval    = delayedQueueInterval;
     _handleRecycleCount      = interval; // Start at interval so the first one will be recycled.
     _maxDelayedQueues        = maxDelayedQueues;
 }
Esempio n. 9
0
        public void DiscardingExceedingElementsWithReleaseAtDifferentThreadTest()
        {
            int maxCapacity    = 32;
            int instancesCount = 0;

            ThreadLocalPool <HandledObject> pool = new ThreadLocalPool <HandledObject>(handle =>
            {
                Interlocked.Increment(ref instancesCount);
                return(new HandledObject(handle));
            }, maxCapacity, 2);

            // Borrow 2 * maxCapacity objects.
            HandledObject[] array = new HandledObject[maxCapacity * 2];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = pool.Take();
            }

            Assert.Equal(array.Length, Volatile.Read(ref instancesCount));
            // Reset counter.
            Interlocked.Exchange(ref instancesCount, 0);

            // Release from other thread.
            Thread thread = new Thread(() =>
            {
                for (int i = 0; i < array.Length; i++)
                {
                    array[i].Release();
                }
            });

            thread.Start();
            thread.Join();

            Assert.Equal(0, Volatile.Read(ref instancesCount));

            // Borrow 2 * maxCapacity objects. Half of them should come from
            // the recycler queue, the other half should be freshly allocated.
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = pool.Take();
            }

            // The implementation uses maxCapacity / 2 as limit per WeakOrderQueue
            Assert.True(array.Length - maxCapacity / 2 <= Volatile.Read(ref instancesCount),
                        "The instances count (" + Volatile.Read(ref instancesCount) + ") must be <= array.length (" + array.Length
                        + ") - maxCapacity (" + maxCapacity + ") / 2 as we not pool all new handles" +
                        " internally");
        }
Esempio n. 10
0
        public void ThreadCanBeCollectedEvenIfHandledObjectIsReferencedTest()
        {
            ThreadLocalPool <HandledObject> pool = NewPool(1024);
            HandledObject           reference    = null;
            WeakReference <Thread>  threadRef    = null;
            WeakReference <XThread> xThreadRef   = null;

            var thread1 = new Thread(() =>
            {
                //Don't know the reason, but thread2 will not be collected without wrapped with thread1
                var thread2 = new Thread(() =>
                {
                    Interlocked.Exchange(ref xThreadRef, new WeakReference <XThread>(XThread.CurrentThread));
                    HandledObject data = pool.Take();
                    // Store a reference to the HandledObject to ensure it is not collected when the run method finish.
                    Interlocked.Exchange(ref reference, data);
                });
                Interlocked.Exchange(ref threadRef, new WeakReference <Thread>(thread2));
                thread2.Start();
                thread2.Join();
                Assert.True(Volatile.Read(ref threadRef)?.TryGetTarget(out _));
                Assert.True(Volatile.Read(ref xThreadRef)?.TryGetTarget(out _));

                GC.KeepAlive(thread2);
                // Null out so it can be collected.
                thread2 = null;
            });

            thread1.Start();
            thread1.Join();

            for (int i = 0; i < 5; ++i)
            {
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
                GC.WaitForPendingFinalizers();

                if (Volatile.Read(ref threadRef)?.TryGetTarget(out _) == true || Volatile.Read(ref xThreadRef)?.TryGetTarget(out _) == true)
                {
                    Thread.Sleep(100);
                }
            }

            Assert.False(Volatile.Read(ref threadRef)?.TryGetTarget(out _));
            Assert.False(Volatile.Read(ref xThreadRef)?.TryGetTarget(out _));

            // Now call recycle after the Thread was collected to ensure this still works...
            reference.Release();
            reference = null;
        }
Esempio n. 11
0
        public void RecycleDisableDrop()
        {
            ThreadLocalPool <HandledObject> recycler = NewPool(1024, 2, 0, 2, 0);
            HandledObject obj = recycler.Take();

            obj.Release();
            HandledObject obj2 = recycler.Take();

            Assert.Same(obj, obj2);
            obj2.Release();
            HandledObject obj3 = recycler.Take();

            Assert.Same(obj, obj3);
            obj3.Release();
        }
Esempio n. 12
0
        public void RecycleDisableDelayedQueueDrop()
        {
            ThreadLocalPool <HandledObject> recycler = NewPool(1024, 2, 1, 2, 0);
            HandledObject o  = recycler.Take();
            HandledObject o2 = recycler.Take();
            HandledObject o3 = recycler.Take();

            Task.Run(() =>
            {
                o.Release();
                o2.Release();
                o3.Release();
            }).Wait();
            // In reverse order
            Assert.Same(o3, recycler.Take());
            Assert.Same(o, recycler.Take());
        }
Esempio n. 13
0
        protected LoopExecutor(IEventLoopGroup parent, IThreadFactory threadFactory, IRejectedExecutionHandler rejectedHandler, TimeSpan breakoutInterval)
            : base(parent, threadFactory, false, int.MaxValue, rejectedHandler)
        {
            _writeRequestPool = new ThreadLocalPool <WriteRequest>(s_valueFactory);

            _preciseBreakoutInterval = ToPreciseTime(breakoutInterval);

            _loop         = new Loop();
            _asyncHandle  = new Async(_loop, OnCallbackAction, this);
            _timerHandle  = new Timer(_loop, OnCallbackAction, this);
            _loopRunStart = new ManualResetEventSlim(false, 1);

            if (SharedConstants.False >= (uint)Interlocked.Exchange(ref s_startTimeInitialized, SharedConstants.True))
            {
                _loop.UpdateTime();
                s_initialTime = _loop.Now;
            }
        }
        void MaxCapacityTest0(int maxCapacity)
        {
            var recycler = new ThreadLocalPool <HandledObject>(handle => new HandledObject(handle), maxCapacity);

            var objects = new HandledObject[maxCapacity * 3];

            for (int i = 0; i < objects.Length; i++)
            {
                objects[i] = recycler.Take();
            }

            for (int i = 0; i < objects.Length; i++)
            {
                objects[i].Release();
                objects[i] = null;
            }
            Assert.Equal(maxCapacity, recycler.ThreadLocalCapacity);
        }
Esempio n. 15
0
        public void ReleaseAtDifferentThreadTest()
        {
            ThreadLocalPool <HandledObject> pool = NewPool(256, 10, 2, 10, 2);

            HandledObject obj    = pool.Take();
            HandledObject obj2   = pool.Take();
            Thread        thread = new Thread(() =>
            {
                obj.Release();
                obj2.Release();
            });

            thread.Start();
            thread.Join();

            Assert.Same(pool.Take(), obj);
            Assert.NotSame(pool.Take(), obj2);
        }
        public void MaxCapacityWithRecycleAtDifferentThreadTest()
        {
            const int maxCapacity = 4; // Choose the number smaller than WeakOrderQueue.LINK_CAPACITY
            var       recycler    = new ThreadLocalPool <HandledObject>(handle => new HandledObject(handle), maxCapacity);

            // Borrow 2 * maxCapacity objects.
            // Return the half from the same thread.
            // Return the other half from the different thread.

            var array = new HandledObject[maxCapacity * 3];

            for (int i = 0; i < array.Length; i++)
            {
                array[i] = recycler.Take();
            }

            for (int i = 0; i < maxCapacity; i++)
            {
                array[i].Release();
            }

            Task.Run(() =>
            {
                for (int i = maxCapacity; i < array.Length; i++)
                {
                    array[i].Release();
                }
            }).Wait();

            Assert.Equal(recycler.ThreadLocalCapacity, maxCapacity);
            Assert.Equal(recycler.ThreadLocalSize, maxCapacity);

            for (int i = 0; i < array.Length; i++)
            {
                recycler.Take();
            }

            Assert.Equal(maxCapacity, recycler.ThreadLocalCapacity);
            Assert.Equal(0, recycler.ThreadLocalSize);
        }
Esempio n. 17
0
 public PooledByteBuffer(ThreadLocalPool.Handle returnHandle, IByteBufferAllocator allocator, int maxFixedCapacity, int maxCapacity)
     : this(returnHandle, allocator, new byte[maxFixedCapacity], maxCapacity)
 {
 }
Esempio n. 18
0
 PendingWrite(ThreadLocalPool.Handle handle)
 {
     this.handle = handle;
 }
Esempio n. 19
0
        public void MaxCapacityWithRecycleAtDifferentThreadTest()
        {
            const int maxCapacity = 4; // Choose the number smaller than WeakOrderQueue.LINK_CAPACITY
            var recycler = new ThreadLocalPool<HandledObject>(handle => new HandledObject(handle), maxCapacity);

            // Borrow 2 * maxCapacity objects.
            // Return the half from the same thread.
            // Return the other half from the different thread.

            var array = new HandledObject[maxCapacity * 3];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = recycler.Take();
            }

            for (int i = 0; i < maxCapacity; i++)
            {
                array[i].Release();
            }

            Task.Run(() =>
            {
                for (int i = maxCapacity; i < array.Length; i++)
                {
                    array[i].Release();
                }
            }).Wait();

            Assert.Equal(recycler.ThreadLocalCapacity, maxCapacity);
            Assert.Equal(recycler.ThreadLocalSize, maxCapacity);

            for (int i = 0; i < array.Length; i++)
            {
                recycler.Take();
            }

            Assert.Equal(maxCapacity, recycler.ThreadLocalCapacity);
            Assert.Equal(0, recycler.ThreadLocalSize);
        }
Esempio n. 20
0
 public RecyclableObject(ThreadLocalPool.Handle handle)
 {
     this.handle = handle;
 }
Esempio n. 21
0
 internal HandledObject(ThreadLocalPool.Handle handle)
 {
     this.handle = handle;
 }
Esempio n. 22
0
 Entry(ThreadLocalPool.Handle handle)
 {
     this.handle = handle;
 }
Esempio n. 23
0
        void MaxCapacityTest(int maxCapacity)
        {
            var recycler = new ThreadLocalPool<HandledObject>(handle => new HandledObject(handle), maxCapacity);

            var objects = new HandledObject[maxCapacity * 3];
            for (int i = 0; i < objects.Length; i++)
            {
                objects[i] = recycler.Take();
            }

            for (int i = 0; i < objects.Length; i++)
            {
                objects[i].Release();
                objects[i] = null;
            }
            Assert.Equal(maxCapacity, recycler.ThreadLocalCapacity);
        }