public void Enter(ref bool lockTaken)
{
if (lockTaken)
throw new ArgumentException ("lockTaken", "lockTaken must be initialized to false");
if (isThreadOwnerTrackingEnabled && IsHeldByCurrentThread)
throw new LockRecursionException ();
int slot = -1;
RuntimeHelpers.PrepareConstrainedRegions ();
try {
slot = Interlocked.Increment (ref ticket.Users) - 1;
ServerSpinWait wait = new ServerSpinWait ();
while (slot != ticket.Value) {
wait.SpinOnce ();
while (stallTickets != null && stallTickets.TryRemove (ticket.Value))
++ticket.Value;
}
} finally {
if (slot == ticket.Value) {
lockTaken = true;
threadWhoTookLock = Thread.CurrentThread.ManagedThreadId;
} else if (slot != -1) {
// We have been interrupted, initialize stallTickets
if (stallTickets == null)
Interlocked.CompareExchange (ref stallTickets, new ServerConcurrentOrderedList<int> (), null);
stallTickets.TryAdd (slot);
}
}
}