示例#1
0
        private ReaderWriterCount GetThreadRWCount(bool dontAllocate)
        {
            ReaderWriterCount rwc   = t_rwc;
            ReaderWriterCount empty = null;

            while (rwc != null)
            {
                if (rwc.lockID == _lockID)
                {
                    return(rwc);
                }

                if (!dontAllocate && empty == null && IsRWEntryEmpty(rwc))
                {
                    empty = rwc;
                }

                rwc = rwc.next;
            }

            if (dontAllocate)
            {
                return(null);
            }

            if (empty == null)
            {
                empty      = new ReaderWriterCount();
                empty.next = t_rwc;
                t_rwc      = empty;
            }

            empty.lockID = _lockID;
            return(empty);
        }
        private ReaderWriterCount GetThreadRWCount(int id, bool DontAllocate)
        {
            int index = id & 0xff;
            ReaderWriterCount count = null;

            if (this.rwc[index] == null)
            {
                if (DontAllocate)
                {
                    return(null);
                }
                this.rwc[index] = new ReaderWriterCount(this.fIsReentrant);
            }
            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];
            }
            ReaderWriterCount next = this.rwc[index].next;

            while (next != null)
            {
                if (next.threadid == id)
                {
                    return(next);
                }
                if ((count == null) && IsRWEntryEmpty(next))
                {
                    count = next;
                }
                next = next.next;
            }
            if (DontAllocate)
            {
                return(null);
            }
            if (count == null)
            {
                next = new ReaderWriterCount(this.fIsReentrant)
                {
                    threadid = id,
                    next     = this.rwc[index].next
                };
                this.rwc[index].next = next;
                return(next);
            }
            count.threadid = id;
            return(count);
        }
示例#3
0
        public void ExitReadLock()
        {
            int id = Thread.CurrentThread.ManagedThreadId;
            ReaderWriterCount lrwc = null;

            EnterMyLock();

            lrwc = GetThreadRWCount(id, true);

            if (!fIsReentrant)
            {
                if (lrwc == null)
                {
                    //You have to be holding the read lock to make this call.
                    ExitMyLock();
                    throw new SynchronizationLockException(SR.GetString(SR.SynchronizationLockException_MisMatchedRead));
                }
            }
            else
            {
                if (lrwc == null || lrwc.readercount < 1)
                {
                    ExitMyLock();
                    throw new SynchronizationLockException(SR.GetString(SR.SynchronizationLockException_MisMatchedRead));
                }

                if (lrwc.readercount > 1)
                {
                    lrwc.readercount--;
                    ExitMyLock();
                    Thread.EndCriticalRegion();
                    return;
                }

                if (id == upgradeLockOwnerId)
                {
                    fUpgradeThreadHoldingRead = false;
                }
            }

            Debug.Assert(owners > 0, "ReleasingReaderLock: releasing lock and no read lock taken");

            --owners;

            Debug.Assert(lrwc.readercount == 1);
            lrwc.readercount--;

            ExitAndWakeUpAppropriateWaiters();
            Thread.EndCriticalRegion();
        }
示例#4
0
 private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
 {
     if (rwc.lockID == 0)
     {
         return(true);
     }
     else if (rwc.readercount == 0 && rwc.writercount == 0 && rwc.upgradecount == 0)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
        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);
        }
示例#6
0
 private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
 {
     if (rwc.threadid == -1)
     {
         return(true);
     }
     else if (rwc.readercount == 0 && rwc.rc == null)
     {
         return(true);
     }
     else if (rwc.readercount == 0 && rwc.rc.writercount == 0 && rwc.rc.upgradecount == 0)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
        public void ExitUpgradeableReadLock()
        {
            int managedThreadId = Thread.CurrentThread.ManagedThreadId;

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

            if (!this.fIsReentrant)
            {
                if (managedThreadId != this.writeLockOwnerId)
                {
                    throw new SynchronizationLockException(System.SR.GetString("SynchronizationLockException_MisMatchedWrite"));
                }
                this.EnterMyLock();
            }
            else
            {
                this.EnterMyLock();
                ReaderWriterCount threadRWCount = this.GetThreadRWCount(managedThreadId, false);
                if (threadRWCount == null)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException(System.SR.GetString("SynchronizationLockException_MisMatchedWrite"));
                }
                RecursiveCounts rc = threadRWCount.rc;
                if (rc.writercount < 1)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException(System.SR.GetString("SynchronizationLockException_MisMatchedWrite"));
                }
                rc.writercount--;
                if (rc.writercount > 0)
                {
                    this.ExitMyLock();
                    Thread.EndCriticalRegion();
                    return;
                }
            }
            this.ClearWriterAcquired();
            this.writeLockOwnerId = -1;
            this.ExitAndWakeUpAppropriateWaiters();
            Thread.EndCriticalRegion();
        }
示例#9
0
        public void ExitReadLock()
        {
            ReaderWriterCount lrwc = null;

            EnterMyLock();

            lrwc = GetThreadRWCount(true);

            if (lrwc == null || lrwc.readercount < 1)
            {
                //You have to be holding the read lock to make this call.
                ExitMyLock();
                throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedRead);
            }

            if (_fIsReentrant)
            {
                if (lrwc.readercount > 1)
                {
                    lrwc.readercount--;
                    ExitMyLock();
                    return;
                }

                if (Environment.CurrentManagedThreadId == _upgradeLockOwnerId)
                {
                    _fUpgradeThreadHoldingRead = false;
                }
            }

            Debug.Assert(_owners > 0, "ReleasingReaderLock: releasing lock and no read lock taken");

            --_owners;

            Debug.Assert(lrwc.readercount == 1);
            lrwc.readercount--;

            ExitAndWakeUpAppropriateWaiters();
        }
        public void ExitReadLock()
        {
            int managedThreadId             = Thread.CurrentThread.ManagedThreadId;
            ReaderWriterCount threadRWCount = null;

            this.EnterMyLock();
            threadRWCount = this.GetThreadRWCount(managedThreadId, true);
            if (!this.fIsReentrant)
            {
                if (threadRWCount == null)
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException(System.SR.GetString("SynchronizationLockException_MisMatchedRead"));
                }
            }
            else
            {
                if ((threadRWCount == null) || (threadRWCount.readercount < 1))
                {
                    this.ExitMyLock();
                    throw new SynchronizationLockException(System.SR.GetString("SynchronizationLockException_MisMatchedRead"));
                }
                if (threadRWCount.readercount > 1)
                {
                    threadRWCount.readercount--;
                    this.ExitMyLock();
                    Thread.EndCriticalRegion();
                    return;
                }
                if (managedThreadId == this.upgradeLockOwnerId)
                {
                    this.fUpgradeThreadHoldingRead = false;
                }
            }
            this.owners--;
            threadRWCount.readercount--;
            this.ExitAndWakeUpAppropriateWaiters();
            Thread.EndCriticalRegion();
        }
示例#11
0
        private bool TryEnterReadLockCore(TimeoutTracker timeout)
        {
            if (_fDisposed)
            {
                throw new ObjectDisposedException(null);
            }

            ReaderWriterCount lrwc = null;
            int id = Environment.CurrentManagedThreadId;

            if (!_fIsReentrant)
            {
                if (id == _writeLockOwnerId)
                {
                    //Check for AW->AR
                    throw new LockRecursionException(SR.LockRecursionException_ReadAfterWriteNotAllowed);
                }

                EnterMyLock();

                lrwc = GetThreadRWCount(false);

                //Check if the reader lock is already acquired. Note, we could
                //check the presence of a reader by not allocating rwc (But that
                //would lead to two lookups in the common case. It's better to keep
                //a count in the structure).
                if (lrwc.readercount > 0)
                {
                    ExitMyLock();
                    throw new LockRecursionException(SR.LockRecursionException_RecursiveReadNotAllowed);
                }
                else if (id == _upgradeLockOwnerId)
                {
                    //The upgrade lock is already held.
                    //Update the global read counts and exit.

                    lrwc.readercount++;
                    _owners++;
                    ExitMyLock();
                    return(true);
                }
            }
            else
            {
                EnterMyLock();
                lrwc = GetThreadRWCount(false);
                if (lrwc.readercount > 0)
                {
                    lrwc.readercount++;
                    ExitMyLock();
                    return(true);
                }
                else if (id == _upgradeLockOwnerId)
                {
                    //The upgrade lock is already held.
                    //Update the global read counts and exit.
                    lrwc.readercount++;
                    _owners++;
                    ExitMyLock();
                    _fUpgradeThreadHoldingRead = true;
                    return(true);
                }
                else if (id == _writeLockOwnerId)
                {
                    //The write lock is already held.
                    //Update global read counts here,
                    lrwc.readercount++;
                    _owners++;
                    ExitMyLock();
                    return(true);
                }
            }

            bool retVal = true;

            int spincount = 0;

            for (; ;)
            {
                // We can enter a read lock if there are only read-locks have been given out
                // and a writer is not trying to get in.

                if (_owners < MAX_READER)
                {
                    // Good case, there is no contention, we are basically done
                    _owners++;       // Indicate we have another reader
                    lrwc.readercount++;
                    break;
                }

                if (spincount < MaxSpinCount)
                {
                    ExitMyLock();
                    if (timeout.IsExpired)
                    {
                        return(false);
                    }
                    spincount++;
                    SpinWait(spincount);
                    EnterMyLock();
                    //The per-thread structure may have been recycled as the lock is acquired (due to message pumping), load again.
                    if (IsRwHashEntryChanged(lrwc))
                    {
                        lrwc = GetThreadRWCount(false);
                    }
                    continue;
                }

                // Drat, we need to wait.  Mark that we have waiters and wait.
                if (_readEvent == null)      // Create the needed event
                {
                    LazyCreateEvent(ref _readEvent, false);
                    if (IsRwHashEntryChanged(lrwc))
                    {
                        lrwc = GetThreadRWCount(false);
                    }
                    continue;   // since we left the lock, start over.
                }

                retVal = WaitOnEvent(_readEvent, ref _numReadWaiters, timeout, isWriteWaiter: false);
                if (!retVal)
                {
                    return(false);
                }
                if (IsRwHashEntryChanged(lrwc))
                {
                    lrwc = GetThreadRWCount(false);
                }
            }

            ExitMyLock();
            return(retVal);
        }
 private ReaderWriterCount GetThreadRWCount(int id, bool DontAllocate)
 {
     int index = id & 0xff;
     ReaderWriterCount count = null;
     if (this.rwc[index] == null)
     {
         if (DontAllocate)
         {
             return null;
         }
         this.rwc[index] = new ReaderWriterCount(this.fIsReentrant);
     }
     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];
     }
     ReaderWriterCount next = this.rwc[index].next;
     while (next != null)
     {
         if (next.threadid == id)
         {
             return next;
         }
         if ((count == null) && IsRWEntryEmpty(next))
         {
             count = next;
         }
         next = next.next;
     }
     if (DontAllocate)
     {
         return null;
     }
     if (count == null)
     {
         next = new ReaderWriterCount(this.fIsReentrant) {
             threadid = id,
             next = this.rwc[index].next
         };
         this.rwc[index].next = next;
         return next;
     }
     count.threadid = id;
     return count;
 }
示例#13
0
 private bool IsRwHashEntryChanged(ReaderWriterCount lrwc)
 {
     return(lrwc.lockID != _lockID);
 }
 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))));
 }
示例#15
0
    /// <summary> 
    /// This routine retrieves/sets the per-thread counts needed to enforce the
    /// various rules related to acquiring the lock. It's a simple hash table, 
    /// where the first entry is pre-allocated for optimizing the common case.
    /// After the first element has been allocated, duplicates are kept of in
    /// linked-list. The entries are never freed, and the max size of the
    /// table would be bounded by the max number of threads that held the lock 
    /// simultaneously.
    /// 
    /// DontAllocate is set to true if the caller just wants to get an existing 
    /// entry for this thread, but doesn't want to add one if an existing one
    /// could not be found. 
    /// </summary>
    private ReaderWriterCount GetThreadRWCount(int id, bool dontAllocate)
    {
      int hash = id & HashTableSize;
      ReaderWriterCount firstfound = null;
#if DEBUG
      Debug.Assert(MyLockHeld);
#endif

      if (null == _rwc[hash])
      {
        if (dontAllocate)
          return null;
        
        _rwc[hash] = new ReaderWriterCount(_isReentrant);
      }

      if (_rwc[hash].ThreadId == id)
      {
        return _rwc[hash];
      }

      if (IsRWEntryEmpty(_rwc[hash]) && !dontAllocate)
      {
        //No more entries in chain, so no more searching required. 
        if (_rwc[hash].Next == null)
        {
          _rwc[hash].ThreadId = id;
          return _rwc[hash];
        }
        
        firstfound = _rwc[hash];
      }

      //SlowPath

      var temp = _rwc[hash].Next;

      while (temp != null)
      {
        if (temp.ThreadId == id)
        {
          return temp;
        }

        if (firstfound == null)
        {
          if (IsRWEntryEmpty(temp))
            firstfound = temp;
        }

        temp = temp.Next;
      }

      if (dontAllocate)
        return null;

      if (firstfound == null)
      {
        temp = new ReaderWriterCount(_isReentrant)
        {
          ThreadId = id,
          Next = _rwc[hash].Next
        };
        _rwc[hash].Next = temp;
        return temp;
      }
      
      firstfound.ThreadId = id;
      return firstfound;
    }
示例#16
0
 private static bool IsRwHashEntryChanged(ReaderWriterCount lrwc, int id)
 {
   return lrwc.ThreadId != id;
 }
示例#17
0
    private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
    {
      if (rwc.ThreadId == -1)
        return true;

      if (rwc.ReaderCount == 0 && rwc.Rc == null)
        return true;

      if (rwc.ReaderCount == 0 && rwc.Rc.WriterCount == 0 && rwc.Rc.UpgradeCount == 0)
        return true;

      return false;
    }
        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);
        }
示例#19
0
        /// <summary>
        /// This routine retrieves/sets the per-thread counts needed to enforce the
        /// various rules related to acquiring the lock. It's a simple hash table,
        /// where the first entry is pre-allocated for optimizing the common case.
        /// After the first element has been allocated, duplicates are kept of in
        /// linked-list. The entries are never freed, and the max size of the
        /// table would be bounded by the max number of threads that held the lock
        /// simultaneously.
        ///
        /// DontAllocate is set to true if the caller just wants to get an existing
        /// entry for this thread, but doesn't want to add one if an existing one
        /// could not be found.
        /// </summary>
        private ReaderWriterCount GetThreadRWCount(int id, bool DontAllocate)
        {
            int hash = id & hashTableSize;
            ReaderWriterCount firstfound = null;

#if DEBUG
            Debug.Assert(MyLockHeld);
#endif

            if (null == rwc[hash])
            {
                if (DontAllocate)
                {
                    return(null);
                }
                else
                {
                    rwc[hash] = new ReaderWriterCount(fIsReentrant);
                }
            }

            if (rwc[hash].threadid == id)
            {
                return(rwc[hash]);
            }

            if (IsRWEntryEmpty(rwc[hash]) && !DontAllocate)
            {
                //No more entries in chain, so no more searching required.
                if (rwc[hash].next == null)
                {
                    rwc[hash].threadid = id;
                    return(rwc[hash]);
                }
                else
                {
                    firstfound = rwc[hash];
                }
            }

            //SlowPath

            ReaderWriterCount temp = rwc[hash].next;

            while (temp != null)
            {
                if (temp.threadid == id)
                {
                    return(temp);
                }

                if (firstfound == null)
                {
                    if (IsRWEntryEmpty(temp))
                    {
                        firstfound = temp;
                    }
                }

                temp = temp.next;
            }

            if (DontAllocate)
            {
                return(null);
            }

            if (firstfound == null)
            {
                temp           = new ReaderWriterCount(fIsReentrant);
                temp.threadid  = id;
                temp.next      = rwc[hash].next;
                rwc[hash].next = temp;
                return(temp);
            }
            else
            {
                firstfound.threadid = id;
                return(firstfound);
            }
        }
示例#20
0
 private bool IsRwHashEntryChanged(ReaderWriterCount lrwc)
 {
     return lrwc.lockID != this.lockID;
 }
        private bool TryEnterReadLockCore(int millisecondsTimeout)
        {
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("millisecondsTimeout");
            }
            if (this.fDisposed)
            {
                throw new ObjectDisposedException(null);
            }
            ReaderWriterCount lrwc = null;
            int managedThreadId    = Thread.CurrentThread.ManagedThreadId;

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

Label_013D:
            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, managedThreadId))
                    {
                        lrwc = this.GetThreadRWCount(managedThreadId, false);
                    }
                }
                else if (this.readEvent == null)
                {
                    this.LazyCreateEvent(ref this.readEvent, false);
                    if (IsRwHashEntryChanged(lrwc, managedThreadId))
                    {
                        lrwc = this.GetThreadRWCount(managedThreadId, false);
                    }
                }
                else
                {
                    flag = this.WaitOnEvent(this.readEvent, ref this.numReadWaiters, millisecondsTimeout);
                    if (!flag)
                    {
                        return(false);
                    }
                    if (IsRwHashEntryChanged(lrwc, managedThreadId))
                    {
                        lrwc = this.GetThreadRWCount(managedThreadId, false);
                    }
                }
                goto Label_013D;
            }
            this.ExitMyLock();
            return(flag);
        }
 private static bool IsRwHashEntryChanged(ReaderWriterCount lrwc, int id)
 {
     return (lrwc.threadid != id);
 }
示例#23
0
 private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
 {
     if (rwc.lockID == 0)
         return true;
     else if (rwc.readercount == 0 && rwc.writercount == 0 && rwc.upgradecount == 0)
         return true;
     else
         return false;
 }
 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))));
 }
示例#25
0
        private ReaderWriterCount GetThreadRWCount(bool dontAllocate)
        {
			ReaderWriterCount rwc = t_rwc;
			ReaderWriterCount empty = null;
			while (rwc != null)
			{
				if (rwc.lockID == this.lockID)
					return rwc;
					
				if (!dontAllocate && empty == null && IsRWEntryEmpty(rwc))
					empty = rwc;

                rwc = rwc.next;
			}
			
			if (dontAllocate)
				return null;

            if (empty == null)
            {
                empty = new ReaderWriterCount();
                empty.next = t_rwc;
                t_rwc = empty;
            }

            empty.lockID = this.lockID;
            return empty;
        }
 private static bool IsRwHashEntryChanged(ReaderWriterCount lrwc, int id)
 {
     return(lrwc.threadid != id);
 }