private LockDetails GetReadLockDetails(int threadId, bool create) { int i; LockDetails lockDetails; for (i = 0; i < read_locks.Length; i++) { lockDetails = read_locks[i]; if (lockDetails == null) { break; } if (lockDetails.ThreadId == threadId) { return(lockDetails); } } if (!create) { return(null); } if (i == read_locks.Length) { Array.Resize(ref read_locks, read_locks.Length * 2); } lockDetails = (read_locks[i] = new LockDetails()); lockDetails.ThreadId = threadId; return(lockDetails); }
LockDetails GetReadLockDetails(int threadId, bool create) { int i; LockDetails ld; for (i = 0; i < read_locks.Length; ++i) { ld = read_locks[i]; if (ld == null) { break; } if (ld.ThreadId == threadId) { return(ld); } } if (!create) { return(null); } if (i == read_locks.Length) { Array.Resize(ref read_locks, read_locks.Length * 2); } ld = read_locks[i] = new LockDetails(); ld.ThreadId = threadId; return(ld); }
public bool TryEnterReadLock(int millisecondsTimeout) { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } if (read_locks == null) { throw new ObjectDisposedException(null); } if (Thread.CurrentThread == write_thread) { throw new LockRecursionException("Read lock cannot be acquired while write lock is held"); } EnterMyLock(); LockDetails readLockDetails = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, create: true); if (readLockDetails.ReadLocks != 0) { ExitMyLock(); throw new LockRecursionException("Recursive read lock can only be aquired in SupportsRecursion mode"); } readLockDetails.ReadLocks++; while (true) { if (owners >= 0 && numWriteWaiters == 0) { owners++; ExitMyLock(); return(true); } if (millisecondsTimeout == 0) { ExitMyLock(); return(false); } if (readEvent == null) { LazyCreateEvent(ref readEvent, makeAutoResetEvent: false); } else if (!WaitOnEvent(readEvent, ref numReadWaiters, millisecondsTimeout)) { break; } } return(false); }
public bool TryEnterWriteLock(int millisecondsTimeout) { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } if (read_locks == null) { throw new ObjectDisposedException(null); } if (IsWriteLockHeld) { throw new LockRecursionException(); } EnterMyLock(); LockDetails readLockDetails = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, create: false); if (readLockDetails != null && readLockDetails.ReadLocks > 0) { ExitMyLock(); throw new LockRecursionException("Write lock cannot be acquired while read lock is held"); } while (true) { if (owners == 0) { owners = -1; write_thread = Thread.CurrentThread; break; } if (owners == 1 && upgradable_thread == Thread.CurrentThread) { owners = -1; write_thread = Thread.CurrentThread; break; } if (millisecondsTimeout == 0) { ExitMyLock(); return(false); } if (upgradable_thread == Thread.CurrentThread) { if (upgradeEvent == null) { LazyCreateEvent(ref upgradeEvent, makeAutoResetEvent: false); continue; } if (numUpgradeWaiters != 0) { ExitMyLock(); throw new ApplicationException("Upgrading lock to writer lock already in process, deadlock"); } if (!WaitOnEvent(upgradeEvent, ref numUpgradeWaiters, millisecondsTimeout)) { return(false); } } else if (writeEvent == null) { LazyCreateEvent(ref writeEvent, makeAutoResetEvent: true); } else if (!WaitOnEvent(writeEvent, ref numWriteWaiters, millisecondsTimeout)) { return(false); } } ExitMyLock(); return(true); }
LockDetails GetReadLockDetails(int threadId, bool create) { int i; LockDetails ld; for (i = 0; i < read_locks.Length; ++i) { ld = read_locks [i]; if (ld == null) break; if (ld.ThreadId == threadId) return ld; } if (!create) return null; if (i == read_locks.Length) Array.Resize (ref read_locks, read_locks.Length * 2); ld = read_locks [i] = new LockDetails (); ld.ThreadId = threadId; return ld; }
public bool TryEnterWriteLock(int millisecondsTimeout) { if (millisecondsTimeout < Timeout.Infinite) { throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } if (read_locks == null) { throw new ObjectDisposedException(null); } if (IsWriteLockHeld) { throw new LockRecursionException(); } EnterMyLock(); LockDetails ld = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, false); if (ld != null && ld.ReadLocks > 0) { ExitMyLock(); throw new LockRecursionException("Write lock cannot be acquired while read lock is held"); } while (true) { // There is no contention, we are done if (owners == 0) { // Indicate that we have a writer owners = -1; write_thread = Thread.CurrentThread; break; } // If we are the thread that took the Upgradable read lock if (owners == 1 && upgradable_thread == Thread.CurrentThread) { owners = -1; write_thread = Thread.CurrentThread; break; } // If the request is to probe. if (millisecondsTimeout == 0) { ExitMyLock(); return(false); } // We need to wait, figure out what kind of waiting. if (upgradable_thread == Thread.CurrentThread) { // We are the upgradable thread, register our interest. if (upgradeEvent == null) { LazyCreateEvent(ref upgradeEvent, false); // since we left the lock, start over. continue; } if (numUpgradeWaiters > 0) { ExitMyLock(); throw new ApplicationException("Upgrading lock to writer lock already in process, deadlock"); } if (!WaitOnEvent(upgradeEvent, ref numUpgradeWaiters, millisecondsTimeout)) { return(false); } } else { if (writeEvent == null) { LazyCreateEvent(ref writeEvent, true); // since we left the lock, retry continue; } if (!WaitOnEvent(writeEvent, ref numWriteWaiters, millisecondsTimeout)) { return(false); } } } Debug.Assert(owners == -1, "Owners is not -1"); ExitMyLock(); return(true); }
public bool TryEnterReadLock(int millisecondsTimeout) { if (millisecondsTimeout < Timeout.Infinite) { throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } if (read_locks == null) { throw new ObjectDisposedException(null); } if (Thread.CurrentThread == write_thread) { throw new LockRecursionException("Read lock cannot be acquired while write lock is held"); } EnterMyLock(); LockDetails ld = GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, true); if (ld.ReadLocks != 0) { ExitMyLock(); throw new LockRecursionException("Recursive read lock can only be acquired in SupportsRecursion mode"); } ++ld.ReadLocks; while (true) { // Easy case, no contention // owners >= 0 means there might be readers (but no writer) if (owners >= 0 && numWriteWaiters == 0) { owners++; break; } // If the request is to probe. if (millisecondsTimeout == 0) { ExitMyLock(); return(false); } // We need to wait. Mark that we have waiters and wait. if (readEvent == null) { LazyCreateEvent(ref readEvent, false); // since we left the lock, start over. continue; } if (!WaitOnEvent(readEvent, ref numReadWaiters, millisecondsTimeout)) { return(false); } } ExitMyLock(); return(true); }