internal override void DoJob(ref Worker wr, Cont <T> tK) { var l = this.l; Spin: var state = l.State; if (state == Lock.Locked) { goto Spin; } if (state != Interlocked.CompareExchange(ref l.State, Lock.Locked, state)) { goto Spin; } if (state == Lock.Free) { goto GotIt; } var waiter = new GotIt(this.l, this.tF, tK); var tail = l.Waiters; if (tail == null) { waiter.Next = waiter; } else { waiter.Next = tail.Next; tail.Next = waiter; } l.Waiters = waiter; l.State = Lock.Held; return; GotIt: // We keep the lock in Locked stated for the duration of the function // call. This avoids doing a second interlocked operation. T value; try { value = this.tF.Invoke(null); } catch (Exception e) { tK = new FailCont <T>(tK, e); value = default(T); } l.State = Lock.Free; Cont.Do(tK, ref wr, value); }
internal override void DoJob(ref Worker wr, Cont <T> tK) { var l = this.l; var tKPrime = new Cont(l, tK); Spin: var state = l.State; if (state == Lock.Locked) { goto Spin; } if (state != Interlocked.CompareExchange(ref l.State, state + 1, state)) { goto Spin; } if (state == Lock.Free) { goto GotIt; } var waiter = new GotIt(tKPrime, this.tJ); var tail = l.Waiters; if (tail == null) { waiter.Next = waiter; } else { waiter.Next = tail.Next; tail.Next = waiter; } l.Waiters = waiter; l.State = Lock.Held; return; GotIt: wr.Handler = tKPrime; this.tJ.DoJob(ref wr, tKPrime); }
public virtual string info(string plus = null) { return(string.Format(plus + "Title: {0}\nRuntime: {1}\nComments: {2}\n rented {3}", Title, PlayingTime, Comment, GotIt.ToString())); }