This commit is contained in:
niko
2026-06-04 11:42:34 +02:00
parent f39ba70a9f
commit e720b98cd1
7488 changed files with 2493818 additions and 0 deletions
@@ -0,0 +1,466 @@
using System;
using System.Collections;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
namespace System.Threading
{
/// <summary>Defines a lock that supports single writers and multiple readers. </summary>
/// <filterpriority>2</filterpriority>
// Token: 0x0200061A RID: 1562
[ComVisible(true)]
public sealed class ReaderWriterLock : CriticalFinalizerObject
{
/// <summary>Initializes a new instance of the <see cref="T:System.Threading.ReaderWriterLock" /> class.</summary>
// Token: 0x06003909 RID: 14601 RVA: 0x000C4A18 File Offset: 0x000C2C18
public ReaderWriterLock()
{
this.writer_queue = new LockQueue(this);
this.reader_locks = new Hashtable();
GC.SuppressFinalize(this);
}
// Token: 0x0600390A RID: 14602 RVA: 0x000C4A50 File Offset: 0x000C2C50
[MonoTODO]
~ReaderWriterLock()
{
}
/// <summary>Gets a value indicating whether the current thread holds a reader lock.</summary>
/// <returns>true if the current thread holds a reader lock; otherwise, false.</returns>
/// <filterpriority>2</filterpriority>
// Token: 0x17000B08 RID: 2824
// (get) Token: 0x0600390B RID: 14603 RVA: 0x000C4A88 File Offset: 0x000C2C88
public bool IsReaderLockHeld
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get
{
bool flag;
lock (this)
{
flag = this.reader_locks.ContainsKey(Thread.CurrentThreadId);
}
return flag;
}
}
/// <summary>Gets a value indicating whether the current thread holds the writer lock.</summary>
/// <returns>true if the current thread holds the writer lock; otherwise, false.</returns>
/// <filterpriority>2</filterpriority>
// Token: 0x17000B09 RID: 2825
// (get) Token: 0x0600390C RID: 14604 RVA: 0x000C4AE4 File Offset: 0x000C2CE4
public bool IsWriterLockHeld
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get
{
bool flag;
lock (this)
{
flag = this.state < 0 && Thread.CurrentThreadId == this.writer_lock_owner;
}
return flag;
}
}
/// <summary>Gets the current sequence number.</summary>
/// <returns>The current sequence number.</returns>
/// <filterpriority>2</filterpriority>
// Token: 0x17000B0A RID: 2826
// (get) Token: 0x0600390D RID: 14605 RVA: 0x000C4B44 File Offset: 0x000C2D44
public int WriterSeqNum
{
get
{
int num;
lock (this)
{
num = this.seq_num;
}
return num;
}
}
/// <summary>Acquires a reader lock, using an <see cref="T:System.Int32" /> value for the time-out.</summary>
/// <param name="millisecondsTimeout">The time-out in milliseconds. </param>
/// <exception cref="T:System.ApplicationException">
/// <paramref name="millisecondsTimeout" /> expires before the lock request is granted. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x0600390E RID: 14606 RVA: 0x000C4B90 File Offset: 0x000C2D90
public void AcquireReaderLock(int millisecondsTimeout)
{
this.AcquireReaderLock(millisecondsTimeout, 1);
}
// Token: 0x0600390F RID: 14607 RVA: 0x000C4B9C File Offset: 0x000C2D9C
private void AcquireReaderLock(int millisecondsTimeout, int initialLockCount)
{
lock (this)
{
if (this.HasWriterLock())
{
this.AcquireWriterLock(millisecondsTimeout, initialLockCount);
}
else
{
object obj = this.reader_locks[Thread.CurrentThreadId];
if (obj == null)
{
this.readers++;
try
{
if (this.state < 0 || !this.writer_queue.IsEmpty)
{
while (Monitor.Wait(this, millisecondsTimeout))
{
if (this.state >= 0)
{
goto IL_89;
}
}
throw new ApplicationException("Timeout expired");
}
IL_89:;
}
finally
{
this.readers--;
}
this.reader_locks[Thread.CurrentThreadId] = initialLockCount;
this.state += initialLockCount;
}
else
{
this.reader_locks[Thread.CurrentThreadId] = (int)obj + 1;
this.state++;
}
}
}
}
/// <summary>Acquires a reader lock, using a <see cref="T:System.TimeSpan" /> value for the time-out.</summary>
/// <param name="timeout">A TimeSpan specifying the time-out period. </param>
/// <exception cref="T:System.ApplicationException">
/// <paramref name="timeout" /> expires before the lock request is granted. </exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="timeout" /> specifies a negative value other than -1 milliseconds. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x06003910 RID: 14608 RVA: 0x000C4CE4 File Offset: 0x000C2EE4
public void AcquireReaderLock(TimeSpan timeout)
{
int num = this.CheckTimeout(timeout);
this.AcquireReaderLock(num, 1);
}
/// <summary>Acquires the writer lock, using an <see cref="T:System.Int32" /> value for the time-out.</summary>
/// <param name="millisecondsTimeout">The time-out in milliseconds. </param>
/// <exception cref="T:System.ApplicationException">
/// <paramref name="timeout" /> expires before the lock request is granted. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x06003911 RID: 14609 RVA: 0x000C4D04 File Offset: 0x000C2F04
public void AcquireWriterLock(int millisecondsTimeout)
{
this.AcquireWriterLock(millisecondsTimeout, 1);
}
// Token: 0x06003912 RID: 14610 RVA: 0x000C4D10 File Offset: 0x000C2F10
private void AcquireWriterLock(int millisecondsTimeout, int initialLockCount)
{
lock (this)
{
if (this.HasWriterLock())
{
this.state--;
}
else
{
if (this.state != 0 || !this.writer_queue.IsEmpty)
{
while (this.writer_queue.Wait(millisecondsTimeout))
{
if (this.state == 0)
{
goto IL_68;
}
}
throw new ApplicationException("Timeout expired");
}
IL_68:
this.state = -initialLockCount;
this.writer_lock_owner = Thread.CurrentThreadId;
this.seq_num++;
}
}
}
/// <summary>Acquires the writer lock, using a <see cref="T:System.TimeSpan" /> value for the time-out.</summary>
/// <param name="timeout">The TimeSpan specifying the time-out period. </param>
/// <exception cref="T:System.ApplicationException">
/// <paramref name="timeout" /> expires before the lock request is granted. </exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="timeout" /> specifies a negative value other than -1 milliseconds. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x06003913 RID: 14611 RVA: 0x000C4DD0 File Offset: 0x000C2FD0
public void AcquireWriterLock(TimeSpan timeout)
{
int num = this.CheckTimeout(timeout);
this.AcquireWriterLock(num, 1);
}
/// <summary>Indicates whether the writer lock has been granted to any thread since the sequence number was obtained.</summary>
/// <returns>true if the writer lock has been granted to any thread since the sequence number was obtained; otherwise, false.</returns>
/// <param name="seqNum">The sequence number. </param>
/// <filterpriority>2</filterpriority>
// Token: 0x06003914 RID: 14612 RVA: 0x000C4DF0 File Offset: 0x000C2FF0
public bool AnyWritersSince(int seqNum)
{
bool flag;
lock (this)
{
flag = this.seq_num > seqNum;
}
return flag;
}
/// <summary>Restores the lock status of the thread to what it was before <see cref="M:System.Threading.ReaderWriterLock.UpgradeToWriterLock(System.Int32)" /> was called.</summary>
/// <param name="lockCookie">A <see cref="T:System.Threading.LockCookie" /> returned by <see cref="M:System.Threading.ReaderWriterLock.UpgradeToWriterLock(System.Int32)" />. </param>
/// <exception cref="T:System.ApplicationException">The thread does not have the writer lock. </exception>
/// <exception cref="T:System.NullReferenceException">The address of <paramref name="lockCookie" /> is a null pointer. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x06003915 RID: 14613 RVA: 0x000C4E40 File Offset: 0x000C3040
public void DowngradeFromWriterLock(ref LockCookie lockCookie)
{
lock (this)
{
if (!this.HasWriterLock())
{
throw new ApplicationException("The thread does not have the writer lock.");
}
this.state = lockCookie.ReaderLocks;
this.reader_locks[Thread.CurrentThreadId] = this.state;
if (this.readers > 0)
{
Monitor.PulseAll(this);
}
}
}
/// <summary>Releases the lock, regardless of the number of times the thread acquired the lock.</summary>
/// <returns>A <see cref="T:System.Threading.LockCookie" /> value representing the released lock.</returns>
/// <filterpriority>2</filterpriority>
// Token: 0x06003916 RID: 14614 RVA: 0x000C4ED4 File Offset: 0x000C30D4
public LockCookie ReleaseLock()
{
LockCookie lockCookie;
lock (this)
{
lockCookie = this.GetLockCookie();
if (lockCookie.WriterLocks != 0)
{
this.ReleaseWriterLock(lockCookie.WriterLocks);
}
else if (lockCookie.ReaderLocks != 0)
{
this.ReleaseReaderLock(lockCookie.ReaderLocks, lockCookie.ReaderLocks);
}
}
return lockCookie;
}
/// <summary>Decrements the lock count.</summary>
/// <exception cref="T:System.ApplicationException">The thread does not have any reader or writer locks. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x06003917 RID: 14615 RVA: 0x000C4F58 File Offset: 0x000C3158
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void ReleaseReaderLock()
{
lock (this)
{
if (!this.HasWriterLock())
{
if (this.state > 0)
{
object obj = this.reader_locks[Thread.CurrentThreadId];
if (obj != null)
{
this.ReleaseReaderLock((int)obj, 1);
return;
}
}
throw new ApplicationException("The thread does not have any reader or writer locks.");
}
this.ReleaseWriterLock();
}
}
// Token: 0x06003918 RID: 14616 RVA: 0x000C4FF0 File Offset: 0x000C31F0
private void ReleaseReaderLock(int currentCount, int releaseCount)
{
int num = currentCount - releaseCount;
if (num == 0)
{
this.reader_locks.Remove(Thread.CurrentThreadId);
}
else
{
this.reader_locks[Thread.CurrentThreadId] = num;
}
this.state -= releaseCount;
if (this.state == 0 && !this.writer_queue.IsEmpty)
{
this.writer_queue.Pulse();
}
}
/// <summary>Decrements the lock count on the writer lock.</summary>
/// <exception cref="T:System.ApplicationException">The thread does not have the writer lock. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x06003919 RID: 14617 RVA: 0x000C5070 File Offset: 0x000C3270
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void ReleaseWriterLock()
{
lock (this)
{
if (!this.HasWriterLock())
{
throw new ApplicationException("The thread does not have the writer lock.");
}
this.ReleaseWriterLock(1);
}
}
// Token: 0x0600391A RID: 14618 RVA: 0x000C50CC File Offset: 0x000C32CC
private void ReleaseWriterLock(int releaseCount)
{
this.state += releaseCount;
if (this.state == 0)
{
if (this.readers > 0)
{
Monitor.PulseAll(this);
}
else if (!this.writer_queue.IsEmpty)
{
this.writer_queue.Pulse();
}
}
}
/// <summary>Restores the lock status of the thread to what it was before calling <see cref="M:System.Threading.ReaderWriterLock.ReleaseLock" />.</summary>
/// <param name="lockCookie">A <see cref="T:System.Threading.LockCookie" /> returned by <see cref="M:System.Threading.ReaderWriterLock.ReleaseLock" />. </param>
/// <exception cref="T:System.NullReferenceException">The address of <paramref name="lockCookie" /> is a null pointer. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x0600391B RID: 14619 RVA: 0x000C5124 File Offset: 0x000C3324
public void RestoreLock(ref LockCookie lockCookie)
{
lock (this)
{
if (lockCookie.WriterLocks != 0)
{
this.AcquireWriterLock(-1, lockCookie.WriterLocks);
}
else if (lockCookie.ReaderLocks != 0)
{
this.AcquireReaderLock(-1, lockCookie.ReaderLocks);
}
}
}
/// <summary>Upgrades a reader lock to the writer lock, using an Int32 value for the time-out.</summary>
/// <returns>A <see cref="T:System.Threading.LockCookie" /> value.</returns>
/// <param name="millisecondsTimeout">The time-out in milliseconds. </param>
/// <exception cref="T:System.ApplicationException">
/// <paramref name="millisecondsTimeout" /> expires before the lock request is granted. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x0600391C RID: 14620 RVA: 0x000C5198 File Offset: 0x000C3398
public LockCookie UpgradeToWriterLock(int millisecondsTimeout)
{
LockCookie lockCookie;
lock (this)
{
lockCookie = this.GetLockCookie();
if (lockCookie.WriterLocks != 0)
{
this.state--;
return lockCookie;
}
if (lockCookie.ReaderLocks != 0)
{
this.ReleaseReaderLock(lockCookie.ReaderLocks, lockCookie.ReaderLocks);
}
}
this.AcquireWriterLock(millisecondsTimeout);
return lockCookie;
}
/// <summary>Upgrades a reader lock to the writer lock, using a TimeSpan value for the time-out.</summary>
/// <returns>A <see cref="T:System.Threading.LockCookie" /> value.</returns>
/// <param name="timeout">The TimeSpan specifying the time-out period. </param>
/// <exception cref="T:System.ApplicationException">
/// <paramref name="timeout" /> expires before the lock request is granted. </exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="timeout" /> specifies a negative value other than -1 milliseconds. </exception>
/// <filterpriority>2</filterpriority>
// Token: 0x0600391D RID: 14621 RVA: 0x000C5228 File Offset: 0x000C3428
public LockCookie UpgradeToWriterLock(TimeSpan timeout)
{
int num = this.CheckTimeout(timeout);
return this.UpgradeToWriterLock(num);
}
// Token: 0x0600391E RID: 14622 RVA: 0x000C5244 File Offset: 0x000C3444
private LockCookie GetLockCookie()
{
LockCookie lockCookie = new LockCookie(Thread.CurrentThreadId);
if (this.HasWriterLock())
{
lockCookie.WriterLocks = -this.state;
}
else
{
object obj = this.reader_locks[Thread.CurrentThreadId];
if (obj != null)
{
lockCookie.ReaderLocks = (int)obj;
}
}
return lockCookie;
}
// Token: 0x0600391F RID: 14623 RVA: 0x000C52A8 File Offset: 0x000C34A8
private bool HasWriterLock()
{
return this.state < 0 && Thread.CurrentThreadId == this.writer_lock_owner;
}
// Token: 0x06003920 RID: 14624 RVA: 0x000C52C8 File Offset: 0x000C34C8
private int CheckTimeout(TimeSpan timeout)
{
int num = (int)timeout.TotalMilliseconds;
if (num < -1)
{
throw new ArgumentOutOfRangeException("timeout", "Number must be either non-negative or -1");
}
return num;
}
// Token: 0x040016FD RID: 5885
private int seq_num = 1;
// Token: 0x040016FE RID: 5886
private int state;
// Token: 0x040016FF RID: 5887
private int readers;
// Token: 0x04001700 RID: 5888
private LockQueue writer_queue;
// Token: 0x04001701 RID: 5889
private Hashtable reader_locks;
// Token: 0x04001702 RID: 5890
private int writer_lock_owner;
}
}