Beispiel #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);
        }
Beispiel #2
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);
        }
Beispiel #3
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();
        }
Beispiel #4
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;
        }
Beispiel #5
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();
        }
Beispiel #6
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());
        }
Beispiel #7
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);
        }