Пример #1
0
        internal static void PickReaders <T>(ref Cont <T> readersVar, T value, ref Worker wr)
        {
            var readers = readersVar;

            if (null == readers)
            {
                return;
            }
            readersVar = null;
            int  me     = 0;
            Work cursor = readers;

TryReader:
            var reader = cursor as Cont <T>;

            cursor = cursor.Next;
            var pk = reader.GetPick(ref me);

            if (null == pk)
            {
                goto GotReader;
            }

TryPick:
            var st = Pick.TryPick(pk);

            if (st > 0)
            {
                goto TryNextReader;
            }
            if (st < 0)
            {
                goto TryPick;
            }

            Pick.SetNacks(ref wr, me, pk);
GotReader:
            reader.Value = value;
            Worker.Push(ref wr, reader);

TryNextReader:
            if (cursor != readers)
            {
                goto TryReader;
            }
        }
Пример #2
0
        internal override void DoJob(ref Worker wr, Cont <int> iK)
        {
TryNextTimed:
            var waitTicks = Timeout.Infinite;
            var tt = this.TopTimed;

            if (null == tt)
            {
                goto Return;
            }

            var tickCount = Environment.TickCount;

            waitTicks = tt.Ticks - tickCount;
            if (waitTicks > 0)
            {
                goto Return;
            }

            this.Lock.Enter();
            tt = this.TopTimed;
            if (null == tt)
            {
                goto ExitAndReturnWithInfinite;
            }

            waitTicks = tt.Ticks - tickCount;
            if (waitTicks > 0)
            {
                goto ExitAndReturn;
            }

            DropTimed();
            this.Lock.Exit();

            var pk = tt.Pick;

            if (null == pk)
            {
                goto GotIt;
            }

TryPick:
            var st = Pick.TryPick(pk);

            if (st > 0)
            {
                goto TryNextTimed;
            }
            if (st < 0)
            {
                goto TryPick;
            }

            Pick.SetNacks(ref wr, tt.Me, pk);

GotIt:
            Worker.Push(ref wr, tt);
            iK.DoCont(ref wr, 0);
            return;

ExitAndReturnWithInfinite:
            waitTicks = Timeout.Infinite;
ExitAndReturn:
            this.Lock.Exit();
Return:
            iK.DoCont(ref wr, waitTicks);
        }
Пример #3
0
        internal static void Signal(ref Worker wr, Nack nk)
        {
Spin:
            var state = nk.State;

            if (state > Initial)
            {
                goto JustExit;            // XXX Can this happen?
            }
            if (state < Initial)
            {
                goto Spin;
            }
            if (Initial != Interlocked.CompareExchange(ref nk.State, state + 1, state))
            {
                goto Spin;
            }

            var takers = nk.Takers;

            if (null == takers)
            {
                goto JustExit;
            }
            nk.Takers = null;
            var  me     = 0;
            Work cursor = takers;

TryTaker:
            var taker = cursor as Cont <Unit>;

            cursor = cursor.Next;
            var pk = taker.GetPick(ref me);

            if (null == pk)
            {
                goto GotTaker;
            }

TryPick:
            var st = Pick.TryPick(pk);

            if (st > 0)
            {
                goto TryNextTaker;
            }
            if (st < 0)
            {
                goto TryPick;
            }

            Pick.SetNacks(ref wr, me, pk);
GotTaker:
            Worker.Push(ref wr, taker);
TryNextTaker:
            if (cursor != takers)
            {
                goto TryTaker;
            }
JustExit:
            return;
        }
Пример #4
0
 internal override void DoJob(ref Worker wr, Cont <Unit> uK)
 {
     // See Worker.RunOnThisThread to understand why this works.
     Worker.Push(ref wr, uK);
 }