private void ActivateNextQueueItemWithValidatedToken(int token) { // see if we can nudge the next waiter lock (_queue) { if (Volatile.Read(ref _token) != token) { Throw.InvalidLockHolder(); } try { if (_queue.Count == 0) { Log($"no pending items to activate"); return; } // there's work to do; get a new token Log($"pending items: {_queue.Count}"); // we're expecting to activate; get a new token speculatively // (needs to be new so the old caller can't double-dispose and // release someone else's lock) Volatile.Write(ref _token, token = LockState.GetNextToken(token)); // try to give the new token to someone while (_queue.Count != 0) { var next = DequeueInsideLock(); if (next.TrySetResult(token)) { Log($"handed lock to {next}"); token = 0; // so we don't release the token return; } else { Log($"lock rejected by {next}"); } } } finally { if (token != 0) // nobody actually wanted it; return it { // (this could be the original token, or a new speculative token) Log("returning unwanted lock"); Volatile.Write(ref _token, LockState.ChangeState(token, LockState.Pending)); } SetNextAsyncTimeoutInsideLock(); } } }