예제 #1
0
        internal static void Send(Ch <T> ch, ref Worker wr, T x)
        {
TryNextTaker:
            ch.Lock.Enter();
            var tail = ch.Takers;

            if (null == tail)
            {
                goto TryGiver;
            }
            var cursor = tail.Next;

            if (tail == cursor)
            {
                ch.Takers = null;
                ch.Lock.Exit();
            }
            else
            {
                tail.Next = cursor.Next;
                ch.Lock.Exit();
                tail = cursor as Cont <T>;
            }

            var taker = tail as Taker <T>;

            if (null == taker)
            {
                goto GotTaker;
            }
            var pkOther = taker.Pick;

TryPickOther:
            var stOther = Pick.TryPick(pkOther);

            if (stOther > 0)
            {
                goto TryNextTaker;
            }
            if (stOther < 0)
            {
                goto TryPickOther;
            }

            Pick.SetNacks(ref wr, taker.Me, pkOther);

            tail = taker.Cont;
GotTaker:
            tail.Value = x;
            Worker.Push(ref wr, tail);
            return;

TryGiver:
            WaitQueue.AddSend(ref ch.Givers, x);
            ch.Lock.Exit();
            return;
        }