Add() приватный Метод

private Add ( InternalTransaction newTx ) : void
newTx InternalTransaction
Результат void
Пример #1
0
        private void AddIter(InternalTransaction txNew)
        {
            BucketSet headBucketSet = this.headBucketSet;

            while (headBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout)
            {
                BucketSet set3 = null;
                do
                {
                    WeakReference nextSetWeak = (WeakReference)headBucketSet.nextSetWeak;
                    BucketSet     target      = null;
                    if (nextSetWeak != null)
                    {
                        target = (BucketSet)nextSetWeak.Target;
                    }
                    if (target == null)
                    {
                        BucketSet     set6       = new BucketSet(this, txNew.AbsoluteTimeout);
                        WeakReference reference5 = new WeakReference(set6);
                        WeakReference reference4 = (WeakReference)Interlocked.CompareExchange(ref headBucketSet.nextSetWeak, reference5, nextSetWeak);
                        if (reference4 == nextSetWeak)
                        {
                            set6.prevSet = headBucketSet;
                        }
                    }
                    else
                    {
                        set3          = headBucketSet;
                        headBucketSet = target;
                    }
                }while (headBucketSet.AbsoluteTimeout > txNew.AbsoluteTimeout);
                if (headBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout)
                {
                    BucketSet     set2       = new BucketSet(this, txNew.AbsoluteTimeout);
                    WeakReference reference3 = new WeakReference(set2);
                    set2.nextSetWeak = set3.nextSetWeak;
                    WeakReference reference2 = (WeakReference)Interlocked.CompareExchange(ref set3.nextSetWeak, reference3, set2.nextSetWeak);
                    if (reference2 == set2.nextSetWeak)
                    {
                        if (reference2 != null)
                        {
                            BucketSet set5 = (BucketSet)reference2.Target;
                            if (set5 != null)
                            {
                                set5.prevSet = set2;
                            }
                        }
                        set2.prevSet = headBucketSet;
                    }
                    headBucketSet = set3;
                    set3          = null;
                }
            }
            headBucketSet.Add(txNew);
        }
Пример #2
0
        private void AddIter(InternalTransaction txNew)
        {
            //
            // Theory of operation.
            //
            // Note that the head bucket contains any transaction with essentially infinite
            // timeout (long.MaxValue).  The list is sorted in decending order.  To add
            // a node the code must walk down the list looking for a set of bucket that matches
            // the absolute timeout value for the transaction.  When it is found it passes
            // the insert down to that set.
            //
            // An importent thing to note about the list is that forward links are all weak
            // references and reverse links are all strong references.  This allows the GC
            // to clean up old links in the list so that they don't need to be removed manually.
            // However if there is still a rooted strong reference to an old link in the
            // chain that link wont fall off the list because there is a strong reference held
            // forward.
            //

            BucketSet currentBucketSet = _headBucketSet;

            while (currentBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout)
            {
                BucketSet lastBucketSet = null;
                do
                {
                    WeakReference nextSetWeak   = (WeakReference)currentBucketSet.nextSetWeak;
                    BucketSet     nextBucketSet = null;
                    if (nextSetWeak != null)
                    {
                        nextBucketSet = (BucketSet)nextSetWeak.Target;
                    }

                    if (nextBucketSet == null)
                    {
                        //
                        // We've reached the end of the list either because nextSetWeak was null or
                        // because its reference was collected.  This code doesn't care.  Make a new
                        // set, attempt to attach it and move on.
                        //
                        BucketSet     newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout);
                        WeakReference newSetWeak   = new WeakReference(newBucketSet);

                        WeakReference oldNextSetWeak = (WeakReference)Interlocked.CompareExchange(
                            ref currentBucketSet.nextSetWeak, newSetWeak, nextSetWeak);
                        if (oldNextSetWeak == nextSetWeak)
                        {
                            // Ladies and Gentlemen we have a winner.
                            newBucketSet.prevSet = currentBucketSet;
                        }

                        // Note that at this point we don't update currentBucketSet.  On the next loop
                        // iteration we should be able to pick up where we left off.
                    }
                    else
                    {
                        lastBucketSet    = currentBucketSet;
                        currentBucketSet = nextBucketSet;
                    }
                }while (currentBucketSet.AbsoluteTimeout > txNew.AbsoluteTimeout);

                if (currentBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout)
                {
                    //
                    // Getting to here means that we've found a slot in the list where this bucket set should go.
                    //
                    BucketSet     newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout);
                    WeakReference newSetWeak   = new WeakReference(newBucketSet);

                    newBucketSet.nextSetWeak = lastBucketSet.nextSetWeak;
                    WeakReference oldNextSetWeak = (WeakReference)Interlocked.CompareExchange(
                        ref lastBucketSet.nextSetWeak, newSetWeak, newBucketSet.nextSetWeak);
                    if (oldNextSetWeak == newBucketSet.nextSetWeak)
                    {
                        // Ladies and Gentlemen we have a winner.
                        if (oldNextSetWeak != null)
                        {
                            BucketSet oldSet = (BucketSet)oldNextSetWeak.Target;
                            if (oldSet != null)
                            {
                                // prev references are just there to root things for the GC.  If this object is
                                // gone we don't really care.
                                oldSet.prevSet = newBucketSet;
                            }
                        }
                        newBucketSet.prevSet = lastBucketSet;
                    }

                    // Special note - We are going to loop back to the BucketSet that preceeds the one we just tried
                    // to insert because we may have lost the race to insert our new BucketSet into the list to another
                    // "Add" thread. By looping back, we check again to see if the BucketSet we just created actually
                    // got added. If it did, we will exit out of the outer loop and add the transaction. But if we
                    // lost the race, we will again try to add a new BucketSet. In the latter case, the BucketSet
                    // we created during the first iteration will simply be Garbage Collected because there are no
                    // strong references to it since we never added the transaction to a bucket and the act of
                    // creating the second BucketSet with remove the backward reference that was created in the
                    // first trip thru the loop.
                    currentBucketSet = lastBucketSet;
                    lastBucketSet    = null;

                    // The outer loop will iterate and pick up where we left off.
                }
            }

            //
            // Great we found a spot.
            //
            currentBucketSet.Add(txNew);
        }