667 lines
27 KiB
C#
667 lines
27 KiB
C#
using System;
|
|
|
|
namespace System.Threading
|
|
{
|
|
/// <summary>Represents a lock that is used to manage access to a resource, allowing multiple threads for reading or exclusive access for writing.</summary>
|
|
// Token: 0x02000053 RID: 83
|
|
public class ReaderWriterLockSlim : IDisposable
|
|
{
|
|
/// <summary>Initializes a new instance of the <see cref="T:System.Threading.ReaderWriterLockSlim" /> class with default property values.</summary>
|
|
// Token: 0x06000474 RID: 1140 RVA: 0x000166A8 File Offset: 0x000148A8
|
|
public ReaderWriterLockSlim()
|
|
{
|
|
}
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="T:System.Threading.ReaderWriterLockSlim" /> class, specifying the lock recursion policy.</summary>
|
|
/// <param name="recursionPolicy">One of the enumeration values that specifies the lock recursion policy. </param>
|
|
// Token: 0x06000475 RID: 1141 RVA: 0x000166BC File Offset: 0x000148BC
|
|
public ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy)
|
|
{
|
|
this.recursionPolicy = recursionPolicy;
|
|
if (recursionPolicy != LockRecursionPolicy.NoRecursion)
|
|
{
|
|
throw new NotImplementedException("recursionPolicy != NoRecursion not currently implemented");
|
|
}
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in read mode.</summary>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered read mode. -or-The recursion number would exceed the capacity of the counter. This limit is so large that applications should never encounter it.</exception>
|
|
// Token: 0x06000477 RID: 1143 RVA: 0x00016704 File Offset: 0x00014904
|
|
public void EnterReadLock()
|
|
{
|
|
this.TryEnterReadLock(-1);
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in read mode, with an optional integer time-out.</summary>
|
|
/// <returns>true if the calling thread entered read mode, otherwise, false.</returns>
|
|
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="F:System.Threading.Timeout.Infinite" />) to wait indefinitely.</param>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">The value of <paramref name="millisecondsTimeout" /> is negative, but it is not equal to <see cref="F:System.Threading.Timeout.Infinite" /> (-1), which is the only negative value allowed. </exception>
|
|
// Token: 0x06000478 RID: 1144 RVA: 0x00016710 File Offset: 0x00014910
|
|
public bool TryEnterReadLock(int millisecondsTimeout)
|
|
{
|
|
if (millisecondsTimeout < -1)
|
|
{
|
|
throw new ArgumentOutOfRangeException("millisecondsTimeout");
|
|
}
|
|
if (this.read_locks == null)
|
|
{
|
|
throw new ObjectDisposedException(null);
|
|
}
|
|
if (Thread.CurrentThread == this.write_thread)
|
|
{
|
|
throw new LockRecursionException("Read lock cannot be acquired while write lock is held");
|
|
}
|
|
this.EnterMyLock();
|
|
ReaderWriterLockSlim.LockDetails readLockDetails = this.GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, true);
|
|
if (readLockDetails.ReadLocks != 0)
|
|
{
|
|
this.ExitMyLock();
|
|
throw new LockRecursionException("Recursive read lock can only be aquired in SupportsRecursion mode");
|
|
}
|
|
readLockDetails.ReadLocks++;
|
|
while (this.owners < 0 || this.numWriteWaiters != 0U)
|
|
{
|
|
if (millisecondsTimeout == 0)
|
|
{
|
|
this.ExitMyLock();
|
|
return false;
|
|
}
|
|
if (this.readEvent == null)
|
|
{
|
|
this.LazyCreateEvent(ref this.readEvent, false);
|
|
}
|
|
else if (!this.WaitOnEvent(this.readEvent, ref this.numReadWaiters, millisecondsTimeout))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
this.owners++;
|
|
this.ExitMyLock();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in read mode, with an optional time-out.</summary>
|
|
/// <returns>true if the calling thread entered read mode, otherwise, false.</returns>
|
|
/// <param name="timeout">The interval to wait, or -1 milliseconds to wait indefinitely. </param>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">The value of <paramref name="timeout" /> is negative, but it is not equal to -1 milliseconds, which is the only negative value allowed.-or-The value of <paramref name="timeout" /> is greater than <see cref="F:System.Int32.MaxValue" /> milliseconds. </exception>
|
|
// Token: 0x06000479 RID: 1145 RVA: 0x0001681C File Offset: 0x00014A1C
|
|
public bool TryEnterReadLock(TimeSpan timeout)
|
|
{
|
|
return this.TryEnterReadLock(ReaderWriterLockSlim.CheckTimeout(timeout));
|
|
}
|
|
|
|
/// <summary>Reduces the recursion count for read mode, and exits read mode if the resulting count is 0 (zero).</summary>
|
|
/// <exception cref="T:System.Threading.SynchronizationLockException">The current thread has not entered the lock in read mode.</exception>
|
|
// Token: 0x0600047A RID: 1146 RVA: 0x0001682C File Offset: 0x00014A2C
|
|
public void ExitReadLock()
|
|
{
|
|
this.EnterMyLock();
|
|
if (this.owners < 1)
|
|
{
|
|
this.ExitMyLock();
|
|
throw new SynchronizationLockException("Releasing lock and no read lock taken");
|
|
}
|
|
this.owners--;
|
|
this.GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, false).ReadLocks--;
|
|
this.ExitAndWakeUpAppropriateWaiters();
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in write mode.</summary>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock in any mode. -or-The current thread has entered read mode, so trying to enter the lock in write mode would create the possibility of a deadlock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
// Token: 0x0600047B RID: 1147 RVA: 0x00016890 File Offset: 0x00014A90
|
|
public void EnterWriteLock()
|
|
{
|
|
this.TryEnterWriteLock(-1);
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in write mode, with an optional time-out.</summary>
|
|
/// <returns>true if the calling thread entered write mode, otherwise, false.</returns>
|
|
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="F:System.Threading.Timeout.Infinite" />) to wait indefinitely.</param>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock. -or-The current thread initially entered the lock in read mode, and therefore trying to enter write mode would create the possibility of a deadlock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">The value of <paramref name="millisecondsTimeout" /> is negative, but it is not equal to <see cref="F:System.Threading.Timeout.Infinite" /> (-1), which is the only negative value allowed. </exception>
|
|
// Token: 0x0600047C RID: 1148 RVA: 0x0001689C File Offset: 0x00014A9C
|
|
public bool TryEnterWriteLock(int millisecondsTimeout)
|
|
{
|
|
if (millisecondsTimeout < -1)
|
|
{
|
|
throw new ArgumentOutOfRangeException("millisecondsTimeout");
|
|
}
|
|
if (this.read_locks == null)
|
|
{
|
|
throw new ObjectDisposedException(null);
|
|
}
|
|
if (this.IsWriteLockHeld)
|
|
{
|
|
throw new LockRecursionException();
|
|
}
|
|
this.EnterMyLock();
|
|
ReaderWriterLockSlim.LockDetails readLockDetails = this.GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, false);
|
|
if (readLockDetails != null && readLockDetails.ReadLocks > 0)
|
|
{
|
|
this.ExitMyLock();
|
|
throw new LockRecursionException("Write lock cannot be acquired while read lock is held");
|
|
}
|
|
while (this.owners != 0)
|
|
{
|
|
if (this.owners == 1 && this.upgradable_thread == Thread.CurrentThread)
|
|
{
|
|
this.owners = -1;
|
|
this.write_thread = Thread.CurrentThread;
|
|
IL_178:
|
|
this.ExitMyLock();
|
|
return true;
|
|
}
|
|
if (millisecondsTimeout == 0)
|
|
{
|
|
this.ExitMyLock();
|
|
return false;
|
|
}
|
|
if (this.upgradable_thread == Thread.CurrentThread)
|
|
{
|
|
if (this.upgradeEvent == null)
|
|
{
|
|
this.LazyCreateEvent(ref this.upgradeEvent, false);
|
|
}
|
|
else
|
|
{
|
|
if (this.numUpgradeWaiters > 0U)
|
|
{
|
|
this.ExitMyLock();
|
|
throw new ApplicationException("Upgrading lock to writer lock already in process, deadlock");
|
|
}
|
|
if (!this.WaitOnEvent(this.upgradeEvent, ref this.numUpgradeWaiters, millisecondsTimeout))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
else if (this.writeEvent == null)
|
|
{
|
|
this.LazyCreateEvent(ref this.writeEvent, true);
|
|
}
|
|
else if (!this.WaitOnEvent(this.writeEvent, ref this.numWriteWaiters, millisecondsTimeout))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
this.owners = -1;
|
|
this.write_thread = Thread.CurrentThread;
|
|
goto IL_178;
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in write mode, with an optional time-out.</summary>
|
|
/// <returns>true if the calling thread entered write mode, otherwise, false.</returns>
|
|
/// <param name="timeout">The interval to wait, or -1 milliseconds to wait indefinitely.</param>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock. -or-The current thread initially entered the lock in read mode, and therefore trying to enter write mode would create the possibility of a deadlock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">The value of <paramref name="timeout" /> is negative, but it is not equal to -1 milliseconds, which is the only negative value allowed.-or-The value of <paramref name="timeout" /> is greater than <see cref="F:System.Int32.MaxValue" /> milliseconds. </exception>
|
|
// Token: 0x0600047D RID: 1149 RVA: 0x00016A28 File Offset: 0x00014C28
|
|
public bool TryEnterWriteLock(TimeSpan timeout)
|
|
{
|
|
return this.TryEnterWriteLock(ReaderWriterLockSlim.CheckTimeout(timeout));
|
|
}
|
|
|
|
/// <summary>Reduces the recursion count for write mode, and exits write mode if the resulting count is 0 (zero).</summary>
|
|
/// <exception cref="T:System.Threading.SynchronizationLockException">The current thread has not entered the lock in write mode.</exception>
|
|
// Token: 0x0600047E RID: 1150 RVA: 0x00016A38 File Offset: 0x00014C38
|
|
public void ExitWriteLock()
|
|
{
|
|
this.EnterMyLock();
|
|
if (this.owners != -1)
|
|
{
|
|
this.ExitMyLock();
|
|
throw new SynchronizationLockException("Calling ExitWriterLock when no write lock is held");
|
|
}
|
|
if (this.upgradable_thread == Thread.CurrentThread)
|
|
{
|
|
this.owners = 1;
|
|
}
|
|
else
|
|
{
|
|
this.owners = 0;
|
|
}
|
|
this.write_thread = null;
|
|
this.ExitAndWakeUpAppropriateWaiters();
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in upgradeable mode.</summary>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock in any mode. -or-The current thread has entered read mode, so trying to enter upgradeable mode would create the possibility of a deadlock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
// Token: 0x0600047F RID: 1151 RVA: 0x00016A98 File Offset: 0x00014C98
|
|
public void EnterUpgradeableReadLock()
|
|
{
|
|
this.TryEnterUpgradeableReadLock(-1);
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in upgradeable mode, with an optional time-out.</summary>
|
|
/// <returns>true if the calling thread entered upgradeable mode, otherwise, false.</returns>
|
|
/// <param name="millisecondsTimeout">The number of milliseconds to wait, or -1 (<see cref="F:System.Threading.Timeout.Infinite" />) to wait indefinitely.</param>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock. -or-The current thread initially entered the lock in read mode, and therefore trying to enter upgradeable mode would create the possibility of a deadlock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">The value of <paramref name="millisecondsTimeout" /> is negative, but it is not equal to <see cref="F:System.Threading.Timeout.Infinite" /> (-1), which is the only negative value allowed. </exception>
|
|
// Token: 0x06000480 RID: 1152 RVA: 0x00016AA4 File Offset: 0x00014CA4
|
|
public bool TryEnterUpgradeableReadLock(int millisecondsTimeout)
|
|
{
|
|
if (millisecondsTimeout < -1)
|
|
{
|
|
throw new ArgumentOutOfRangeException("millisecondsTimeout");
|
|
}
|
|
if (this.read_locks == null)
|
|
{
|
|
throw new ObjectDisposedException(null);
|
|
}
|
|
if (this.IsUpgradeableReadLockHeld)
|
|
{
|
|
throw new LockRecursionException();
|
|
}
|
|
if (this.IsWriteLockHeld)
|
|
{
|
|
throw new LockRecursionException();
|
|
}
|
|
this.EnterMyLock();
|
|
while (this.owners != 0 || this.numWriteWaiters != 0U || this.upgradable_thread != null)
|
|
{
|
|
if (millisecondsTimeout == 0)
|
|
{
|
|
this.ExitMyLock();
|
|
return false;
|
|
}
|
|
if (this.readEvent == null)
|
|
{
|
|
this.LazyCreateEvent(ref this.readEvent, false);
|
|
}
|
|
else if (!this.WaitOnEvent(this.readEvent, ref this.numReadWaiters, millisecondsTimeout))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
this.owners++;
|
|
this.upgradable_thread = Thread.CurrentThread;
|
|
this.ExitMyLock();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>Tries to enter the lock in upgradeable mode, with an optional time-out.</summary>
|
|
/// <returns>true if the calling thread entered upgradeable mode, otherwise, false.</returns>
|
|
/// <param name="timeout">The interval to wait, or -1 milliseconds to wait indefinitely.</param>
|
|
/// <exception cref="T:System.Threading.LockRecursionException">The <see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy" /> property is <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion" /> and the current thread has already entered the lock. -or-The current thread initially entered the lock in read mode, and therefore trying to enter upgradeable mode would create the possibility of a deadlock. -or-The recursion number would exceed the capacity of the counter. The limit is so large that applications should never encounter it.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">The value of <paramref name="timeout" /> is negative, but it is not equal to -1 milliseconds, which is the only negative value allowed.-or-The value of <paramref name="timeout" /> is greater than <see cref="F:System.Int32.MaxValue" /> milliseconds. </exception>
|
|
// Token: 0x06000481 RID: 1153 RVA: 0x00016B90 File Offset: 0x00014D90
|
|
public bool TryEnterUpgradeableReadLock(TimeSpan timeout)
|
|
{
|
|
return this.TryEnterUpgradeableReadLock(ReaderWriterLockSlim.CheckTimeout(timeout));
|
|
}
|
|
|
|
/// <summary>Reduces the recursion count for upgradeable mode, and exits upgradeable mode if the resulting count is 0 (zero).</summary>
|
|
/// <exception cref="T:System.Threading.SynchronizationLockException">The current thread has not entered the lock in upgradeable mode.</exception>
|
|
// Token: 0x06000482 RID: 1154 RVA: 0x00016BA0 File Offset: 0x00014DA0
|
|
public void ExitUpgradeableReadLock()
|
|
{
|
|
this.EnterMyLock();
|
|
this.owners--;
|
|
this.upgradable_thread = null;
|
|
this.ExitAndWakeUpAppropriateWaiters();
|
|
}
|
|
|
|
/// <summary>Releases all resources used by the current instance of the <see cref="T:System.Threading.ReaderWriterLockSlim" /> class.</summary>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x06000483 RID: 1155 RVA: 0x00016BC4 File Offset: 0x00014DC4
|
|
public void Dispose()
|
|
{
|
|
this.read_locks = null;
|
|
}
|
|
|
|
/// <summary>Gets a value that indicates whether the current thread has entered the lock in read mode.</summary>
|
|
/// <returns>true if the current thread has entered read mode; otherwise, false.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x1700004B RID: 75
|
|
// (get) Token: 0x06000484 RID: 1156 RVA: 0x00016BD0 File Offset: 0x00014DD0
|
|
public bool IsReadLockHeld
|
|
{
|
|
get
|
|
{
|
|
return this.RecursiveReadCount != 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets a value that indicates whether the current thread has entered the lock in write mode.</summary>
|
|
/// <returns>true if the current thread has entered write mode; otherwise, false.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x1700004C RID: 76
|
|
// (get) Token: 0x06000485 RID: 1157 RVA: 0x00016BE0 File Offset: 0x00014DE0
|
|
public bool IsWriteLockHeld
|
|
{
|
|
get
|
|
{
|
|
return this.RecursiveWriteCount != 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets a value that indicates whether the current thread has entered the lock in upgradeable mode. </summary>
|
|
/// <returns>true if the current thread has entered upgradeable mode; otherwise, false.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x1700004D RID: 77
|
|
// (get) Token: 0x06000486 RID: 1158 RVA: 0x00016BF0 File Offset: 0x00014DF0
|
|
public bool IsUpgradeableReadLockHeld
|
|
{
|
|
get
|
|
{
|
|
return this.RecursiveUpgradeCount != 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the total number of unique threads that have entered the lock in read mode.</summary>
|
|
/// <returns>The number of unique threads that have entered the lock in read mode.</returns>
|
|
// Token: 0x1700004E RID: 78
|
|
// (get) Token: 0x06000487 RID: 1159 RVA: 0x00016C00 File Offset: 0x00014E00
|
|
public int CurrentReadCount
|
|
{
|
|
get
|
|
{
|
|
return this.owners & 268435455;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the number of times the current thread has entered the lock in read mode, as an indication of recursion.</summary>
|
|
/// <returns>0 (zero) if the current thread has not entered read mode, 1 if the thread has entered read mode but has not entered it recursively, or n if the thread has entered the lock recursively n - 1 times.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x1700004F RID: 79
|
|
// (get) Token: 0x06000488 RID: 1160 RVA: 0x00016C10 File Offset: 0x00014E10
|
|
public int RecursiveReadCount
|
|
{
|
|
get
|
|
{
|
|
this.EnterMyLock();
|
|
ReaderWriterLockSlim.LockDetails readLockDetails = this.GetReadLockDetails(Thread.CurrentThread.ManagedThreadId, false);
|
|
int num = ((readLockDetails != null) ? readLockDetails.ReadLocks : 0);
|
|
this.ExitMyLock();
|
|
return num;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the number of times the current thread has entered the lock in upgradeable mode, as an indication of recursion.</summary>
|
|
/// <returns>0 if the current thread has not entered upgradeable mode, 1 if the thread has entered upgradeable mode but has not entered it recursively, or n if the thread has entered upgradeable mode recursively n - 1 times.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x17000050 RID: 80
|
|
// (get) Token: 0x06000489 RID: 1161 RVA: 0x00016C50 File Offset: 0x00014E50
|
|
public int RecursiveUpgradeCount
|
|
{
|
|
get
|
|
{
|
|
return (this.upgradable_thread != Thread.CurrentThread) ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the number of times the current thread has entered the lock in write mode, as an indication of recursion.</summary>
|
|
/// <returns>0 if the current thread has not entered write mode, 1 if the thread has entered write mode but has not entered it recursively, or n if the thread has entered write mode recursively n - 1 times.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x17000051 RID: 81
|
|
// (get) Token: 0x0600048A RID: 1162 RVA: 0x00016C6C File Offset: 0x00014E6C
|
|
public int RecursiveWriteCount
|
|
{
|
|
get
|
|
{
|
|
return (this.write_thread != Thread.CurrentThread) ? 0 : 1;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the total number of threads that are waiting to enter the lock in read mode.</summary>
|
|
/// <returns>The total number of threads that are waiting to enter read mode.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x17000052 RID: 82
|
|
// (get) Token: 0x0600048B RID: 1163 RVA: 0x00016C88 File Offset: 0x00014E88
|
|
public int WaitingReadCount
|
|
{
|
|
get
|
|
{
|
|
return (int)this.numReadWaiters;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the total number of threads that are waiting to enter the lock in upgradeable mode.</summary>
|
|
/// <returns>The total number of threads that are waiting to enter upgradeable mode.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x17000053 RID: 83
|
|
// (get) Token: 0x0600048C RID: 1164 RVA: 0x00016C90 File Offset: 0x00014E90
|
|
public int WaitingUpgradeCount
|
|
{
|
|
get
|
|
{
|
|
return (int)this.numUpgradeWaiters;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets the total number of threads that are waiting to enter the lock in write mode.</summary>
|
|
/// <returns>The total number of threads that are waiting to enter write mode.</returns>
|
|
/// <filterpriority>2</filterpriority>
|
|
// Token: 0x17000054 RID: 84
|
|
// (get) Token: 0x0600048D RID: 1165 RVA: 0x00016C98 File Offset: 0x00014E98
|
|
public int WaitingWriteCount
|
|
{
|
|
get
|
|
{
|
|
return (int)this.numWriteWaiters;
|
|
}
|
|
}
|
|
|
|
/// <summary>Gets a value that indicates the recursion policy for the current <see cref="T:System.Threading.ReaderWriterLockSlim" /> object.</summary>
|
|
/// <returns>One of the enumeration values that specifies the lock recursion policy.</returns>
|
|
// Token: 0x17000055 RID: 85
|
|
// (get) Token: 0x0600048E RID: 1166 RVA: 0x00016CA0 File Offset: 0x00014EA0
|
|
public LockRecursionPolicy RecursionPolicy
|
|
{
|
|
get
|
|
{
|
|
return this.recursionPolicy;
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600048F RID: 1167 RVA: 0x00016CA8 File Offset: 0x00014EA8
|
|
private void EnterMyLock()
|
|
{
|
|
if (Interlocked.CompareExchange(ref this.myLock, 1, 0) != 0)
|
|
{
|
|
this.EnterMyLockSpin();
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000490 RID: 1168 RVA: 0x00016CC4 File Offset: 0x00014EC4
|
|
private void EnterMyLockSpin()
|
|
{
|
|
int num = 0;
|
|
for (;;)
|
|
{
|
|
if (num < 3 && ReaderWriterLockSlim.smp)
|
|
{
|
|
Thread.SpinWait(20);
|
|
}
|
|
else
|
|
{
|
|
Thread.Sleep(0);
|
|
}
|
|
if (Interlocked.CompareExchange(ref this.myLock, 1, 0) == 0)
|
|
{
|
|
break;
|
|
}
|
|
num++;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000491 RID: 1169 RVA: 0x00016D18 File Offset: 0x00014F18
|
|
private void ExitMyLock()
|
|
{
|
|
this.myLock = 0;
|
|
}
|
|
|
|
// Token: 0x17000056 RID: 86
|
|
// (get) Token: 0x06000492 RID: 1170 RVA: 0x00016D24 File Offset: 0x00014F24
|
|
private bool MyLockHeld
|
|
{
|
|
get
|
|
{
|
|
return this.myLock != 0;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000493 RID: 1171 RVA: 0x00016D34 File Offset: 0x00014F34
|
|
private void ExitAndWakeUpAppropriateWaiters()
|
|
{
|
|
if (this.owners == 1 && this.numUpgradeWaiters != 0U)
|
|
{
|
|
this.ExitMyLock();
|
|
this.upgradeEvent.Set();
|
|
}
|
|
else if (this.owners == 0 && this.numWriteWaiters > 0U)
|
|
{
|
|
this.ExitMyLock();
|
|
this.writeEvent.Set();
|
|
}
|
|
else if (this.owners >= 0 && this.numReadWaiters != 0U)
|
|
{
|
|
this.ExitMyLock();
|
|
this.readEvent.Set();
|
|
}
|
|
else
|
|
{
|
|
this.ExitMyLock();
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000494 RID: 1172 RVA: 0x00016DD4 File Offset: 0x00014FD4
|
|
private void LazyCreateEvent(ref EventWaitHandle waitEvent, bool makeAutoResetEvent)
|
|
{
|
|
this.ExitMyLock();
|
|
EventWaitHandle eventWaitHandle;
|
|
if (makeAutoResetEvent)
|
|
{
|
|
eventWaitHandle = new AutoResetEvent(false);
|
|
}
|
|
else
|
|
{
|
|
eventWaitHandle = new ManualResetEvent(false);
|
|
}
|
|
this.EnterMyLock();
|
|
if (waitEvent == null)
|
|
{
|
|
waitEvent = eventWaitHandle;
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000495 RID: 1173 RVA: 0x00016E10 File Offset: 0x00015010
|
|
private bool WaitOnEvent(EventWaitHandle waitEvent, ref uint numWaiters, int millisecondsTimeout)
|
|
{
|
|
waitEvent.Reset();
|
|
numWaiters += 1U;
|
|
bool flag = false;
|
|
this.ExitMyLock();
|
|
try
|
|
{
|
|
flag = waitEvent.WaitOne(millisecondsTimeout, false);
|
|
}
|
|
finally
|
|
{
|
|
this.EnterMyLock();
|
|
numWaiters -= 1U;
|
|
if (!flag)
|
|
{
|
|
this.ExitMyLock();
|
|
}
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
// Token: 0x06000496 RID: 1174 RVA: 0x00016E78 File Offset: 0x00015078
|
|
private static int CheckTimeout(TimeSpan timeout)
|
|
{
|
|
int num;
|
|
try
|
|
{
|
|
num = checked((int)timeout.TotalMilliseconds);
|
|
}
|
|
catch (OverflowException)
|
|
{
|
|
throw new ArgumentOutOfRangeException("timeout");
|
|
}
|
|
return num;
|
|
}
|
|
|
|
// Token: 0x06000497 RID: 1175 RVA: 0x00016EC8 File Offset: 0x000150C8
|
|
private ReaderWriterLockSlim.LockDetails GetReadLockDetails(int threadId, bool create)
|
|
{
|
|
int i;
|
|
ReaderWriterLockSlim.LockDetails lockDetails;
|
|
for (i = 0; i < this.read_locks.Length; i++)
|
|
{
|
|
lockDetails = this.read_locks[i];
|
|
if (lockDetails == null)
|
|
{
|
|
break;
|
|
}
|
|
if (lockDetails.ThreadId == threadId)
|
|
{
|
|
return lockDetails;
|
|
}
|
|
}
|
|
if (!create)
|
|
{
|
|
return null;
|
|
}
|
|
if (i == this.read_locks.Length)
|
|
{
|
|
Array.Resize<ReaderWriterLockSlim.LockDetails>(ref this.read_locks, this.read_locks.Length * 2);
|
|
}
|
|
lockDetails = (this.read_locks[i] = new ReaderWriterLockSlim.LockDetails());
|
|
lockDetails.ThreadId = threadId;
|
|
return lockDetails;
|
|
}
|
|
|
|
// Token: 0x04000115 RID: 277
|
|
private static readonly bool smp = Environment.ProcessorCount > 1;
|
|
|
|
// Token: 0x04000116 RID: 278
|
|
private int myLock;
|
|
|
|
// Token: 0x04000117 RID: 279
|
|
private int owners;
|
|
|
|
// Token: 0x04000118 RID: 280
|
|
private Thread upgradable_thread;
|
|
|
|
// Token: 0x04000119 RID: 281
|
|
private Thread write_thread;
|
|
|
|
// Token: 0x0400011A RID: 282
|
|
private uint numWriteWaiters;
|
|
|
|
// Token: 0x0400011B RID: 283
|
|
private uint numReadWaiters;
|
|
|
|
// Token: 0x0400011C RID: 284
|
|
private uint numUpgradeWaiters;
|
|
|
|
// Token: 0x0400011D RID: 285
|
|
private EventWaitHandle writeEvent;
|
|
|
|
// Token: 0x0400011E RID: 286
|
|
private EventWaitHandle readEvent;
|
|
|
|
// Token: 0x0400011F RID: 287
|
|
private EventWaitHandle upgradeEvent;
|
|
|
|
// Token: 0x04000120 RID: 288
|
|
private readonly LockRecursionPolicy recursionPolicy;
|
|
|
|
// Token: 0x04000121 RID: 289
|
|
private ReaderWriterLockSlim.LockDetails[] read_locks = new ReaderWriterLockSlim.LockDetails[8];
|
|
|
|
// Token: 0x02000054 RID: 84
|
|
private sealed class LockDetails
|
|
{
|
|
// Token: 0x04000122 RID: 290
|
|
public int ThreadId;
|
|
|
|
// Token: 0x04000123 RID: 291
|
|
public int ReadLocks;
|
|
}
|
|
}
|
|
}
|