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; } }
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); }
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; }
internal override void DoJob(ref Worker wr, Cont <Unit> uK) { // See Worker.RunOnThisThread to understand why this works. Worker.Push(ref wr, uK); }