示例#1
0
            public void Release <T>(T value)
                where T : class
            {
                Contract.Requires(value == this.Value, "value differs from one backed by this handle.");

                Stack  stack  = this.Stack;
                Thread thread = Thread.CurrentThread;

                if (stack.Thread == thread)
                {
                    stack.Push(this);
                    return;
                }

                ConditionalWeakTable <Stack, WeakOrderQueue> queueDictionary = DelayedPool.Value;
                WeakOrderQueue delayedRecycled;

                if (!queueDictionary.TryGetValue(stack, out delayedRecycled))
                {
                    var newQueue = new WeakOrderQueue(stack, thread);
                    delayedRecycled = newQueue;
                    queueDictionary.Add(stack, delayedRecycled);
                }
                delayedRecycled.Add(this);
            }
示例#2
0
            internal WeakOrderQueue(Stack stack, Thread thread)
            {
                Contract.Requires(stack != null);

                this.ownerThread = new WeakReference <Thread>(thread);
                this.head        = this.tail = new Link();
                lock (stack)
                {
                    this.next       = stack.HeadQueue;
                    stack.HeadQueue = this;
                }
            }
示例#3
0
            bool Scavenge()
            {
                // continue an existing scavenge, if any
                if (this.ScavengeSome())
                {
                    return(true);
                }

                // reset our scavenge cursor
                this.prevQueue   = null;
                this.cursorQueue = this.HeadQueue;
                return(false);
            }
示例#4
0
            bool ScavengeSome()
            {
                WeakOrderQueue cursor = this.cursorQueue;

                if (cursor == null)
                {
                    cursor = this.HeadQueue;
                    if (cursor == null)
                    {
                        return(false);
                    }
                }

                bool           success = false;
                WeakOrderQueue prev    = this.prevQueue;

                do
                {
                    if (cursor.Transfer(this))
                    {
                        success = true;
                        break;
                    }

                    WeakOrderQueue next = cursor.next;
                    Thread         ownerThread;
                    if (!cursor.ownerThread.TryGetTarget(out ownerThread))
                    {
                        // If the thread associated with the queue is gone, unlink it, after
                        // performing a volatile read to confirm there is no data left to collect.
                        // We never unlink the first queue, as we don't want to synchronize on updating the head.
                        if (!cursor.IsEmpty)
                        {
                            for (;;)
                            {
                                if (cursor.Transfer(this))
                                {
                                    success = true;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        if (prev != null)
                        {
                            prev.next = next;
                        }
                    }
                    else
                    {
                        prev = cursor;
                    }

                    cursor = next;
                }while (cursor != null && !success);

                this.prevQueue   = prev;
                this.cursorQueue = cursor;
                return(success);
            }