private ReaderWriterCount GetThreadRWCount(int id, bool DontAllocate)
        {
            ReaderWriterCount rwc;
            int index = id & 0xff;
            ReaderWriterCount count = null;

            if (this.rwc[index].threadid == id)
            {
                return(this.rwc[index]);
            }
            if (IsRWEntryEmpty(this.rwc[index]) && !DontAllocate)
            {
                if (this.rwc[index].next == null)
                {
                    this.rwc[index].threadid = id;
                    return(this.rwc[index]);
                }
                count = this.rwc[index];
            }
            for (rwc = this.rwc[index].next; rwc != null; rwc = rwc.next)
            {
                if (rwc.threadid == id)
                {
                    return(rwc);
                }
                if ((count == null) && IsRWEntryEmpty(rwc))
                {
                    count = rwc;
                }
            }
            if (DontAllocate)
            {
                return(null);
            }
            if (count == null)
            {
                rwc                  = new ReaderWriterCount(this.fIsReentrant);
                rwc.threadid         = id;
                rwc.next             = this.rwc[index].next;
                this.rwc[index].next = rwc;
                return(rwc);
            }
            count.threadid = id;
            return(count);
        }
        public void ExitUpgradeableReadLock()
        {
            int id = Thread.CurrentThread.ManagedThreadId;

            if (!this.fIsReentrant)
            {
                if (id != this.upgradeLockOwnerId)
                {
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedUpgrade");
                }
                this.EnterMyLock();
            }
            else
            {
                this.EnterMyLock();
                ReaderWriterCount threadRWCount = this.GetThreadRWCount(id, true);
                if (threadRWCount == null)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedUpgrade");
                }
                RecursiveCounts rc = threadRWCount.rc;
                if (rc.upgradecount < 1)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedUpgrade");
                }
                rc.upgradecount--;
                if (rc.upgradecount > 0)
                {
                    this.ExitMyLock();
                    return;
                }
                this.fUpgradeThreadHoldingRead = false;
            }
            this.owners--;
            this.upgradeLockOwnerId = -1;
            this.ExitAndWakeUpAppropriateWaiters();
        }
        public void ExitWriteLock()
        {
            int id = Thread.CurrentThread.ManagedThreadId;

            if (!this.fIsReentrant)
            {
                if (id != this.writeLockOwnerId)
                {
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedWrite");
                }
                this.EnterMyLock();
            }
            else
            {
                this.EnterMyLock();
                ReaderWriterCount threadRWCount = this.GetThreadRWCount(id, false);
                if (threadRWCount == null)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedWrite");
                }
                RecursiveCounts rc = threadRWCount.rc;
                if (rc.writercount < 1)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedWrite");
                }
                rc.writercount--;
                if (rc.writercount > 0)
                {
                    this.ExitMyLock();
                    return;
                }
            }
            this.ClearWriterAcquired();
            this.writeLockOwnerId = -1;
            this.ExitAndWakeUpAppropriateWaiters();
        }
        public void ExitReadLock()
        {
            int id = Thread.CurrentThread.ManagedThreadId;
            ReaderWriterCount threadRWCount = null;

            this.EnterMyLock();
            threadRWCount = this.GetThreadRWCount(id, true);
            if (!this.fIsReentrant)
            {
                if (threadRWCount == null)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedRead");
                }
            }
            else
            {
                if ((threadRWCount == null) || (threadRWCount.readercount < 1))
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException("SynchronizationLockException_MisMatchedRead");
                }
                if (threadRWCount.readercount > 1)
                {
                    threadRWCount.readercount--;
                    this.ExitMyLock();
                    return;
                }
                if (id == this.upgradeLockOwnerId)
                {
                    this.fUpgradeThreadHoldingRead = false;
                }
            }
            this.owners--;
            threadRWCount.readercount--;
            this.ExitAndWakeUpAppropriateWaiters();
        }
        public bool TryEnterReadLock(int millisecondsTimeout)
        {
            ReaderWriterCount lrwc = null;
            int id = Thread.CurrentThread.ManagedThreadId;

            if (!this.fIsReentrant)
            {
                if (id == this.writeLockOwnerId)
                {
                    throw new LockRecursionException("LockRecursionException_ReadAfterWriteNotAllowed");
                }
                this.EnterMyLock();
                lrwc = this.GetThreadRWCount(id, false);
                if (lrwc.readercount > 0)
                {
                    this.ExitMyLock();
                    throw new LockRecursionException("LockRecursionException_RecursiveReadNotAllowed");
                }
                if (id == this.upgradeLockOwnerId)
                {
                    lrwc.readercount++;
                    this.owners++;
                    this.ExitMyLock();
                    return(true);
                }
            }
            else
            {
                this.EnterMyLock();
                lrwc = this.GetThreadRWCount(id, false);
                if (lrwc.readercount > 0)
                {
                    lrwc.readercount++;
                    this.ExitMyLock();
                    return(true);
                }
                if (id == this.upgradeLockOwnerId)
                {
                    lrwc.readercount++;
                    this.owners++;
                    this.ExitMyLock();
                    this.fUpgradeThreadHoldingRead = true;
                    return(true);
                }
                if (id == this.writeLockOwnerId)
                {
                    lrwc.readercount++;
                    this.owners++;
                    this.ExitMyLock();
                    return(true);
                }
            }
            bool flag      = true;
            int  spinCount = 0;

Label_011F:
            if (this.owners < 0xffffffe)
            {
                this.owners++;
                lrwc.readercount++;
            }
            else
            {
                if (spinCount < 20)
                {
                    this.ExitMyLock();
                    if (millisecondsTimeout == 0)
                    {
                        return(false);
                    }
                    spinCount++;
                    SpinWait(spinCount);
                    this.EnterMyLock();
                    if (IsRwHashEntryChanged(lrwc, id))
                    {
                        lrwc = this.GetThreadRWCount(id, false);
                    }
                }
                else if (this.readEvent == null)
                {
                    this.LazyCreateEvent(ref this.readEvent, false);
                    if (IsRwHashEntryChanged(lrwc, id))
                    {
                        lrwc = this.GetThreadRWCount(id, false);
                    }
                }
                else
                {
                    flag = this.WaitOnEvent(this.readEvent, ref this.numReadWaiters, millisecondsTimeout);
                    if (!flag)
                    {
                        return(false);
                    }
                    if (IsRwHashEntryChanged(lrwc, id))
                    {
                        lrwc = this.GetThreadRWCount(id, false);
                    }
                }
                goto Label_011F;
            }
            this.ExitMyLock();
            return(flag);
        }
 private static bool IsRwHashEntryChanged(ReaderWriterCount lrwc, int id)
 {
     return(lrwc.threadid != id);
 }
 private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
 {
     return((rwc.threadid == -1) || (((rwc.readercount == 0) && (rwc.rc == null)) || (((rwc.readercount == 0) && (rwc.rc.writercount == 0)) && (rwc.rc.upgradecount == 0))));
 }