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)))); }