private void WaitForWrite(WaitingToken wait)
        {
            int retry = 0;

            while (true)
            {
                // Check if out token is the next and all readers has left
                if (Interlocked.CompareExchange(ref this.sentinelToken.Next, wait, wait) == wait &&
                    Interlocked.CompareExchange(ref this.readerCount, 0, 0) == 0)
                {
                    return;
                }

                LightweightSpinLock.SpinWait(ref retry);
            }
        }
        public void Enter()
        {
            if (Interlocked.CompareExchange(ref this.held, 1, 0) == 0)
            {
                return;
            }

            int retry = 0;

            while (true)
            {
                LightweightSpinLock.SpinWait(ref retry);

                if ((this.held == 0) && (Interlocked.CompareExchange(ref this.held, 1, 0) == 0))
                {
                    return;
                }
            }
        }
        public void EnterRead()
        {
            int retry = 0;

            while (true)
            {
                if (Interlocked.CompareExchange(ref this.writerPending, 0, 0) == 0)
                {
                    this.innerLock.Enter();

                    if (Interlocked.CompareExchange(ref this.writerPending, 0, 0) == 0)
                    {
                        Interlocked.Increment(ref this.readerCount);
                    }

                    this.innerLock.Exit();
                    break;
                }

                LightweightSpinLock.SpinWait(ref retry);
            }
        }