📄 readerwriterlockslim.cs
字号:
namespace NCindy.Threading
{
using System;
using System.Security.Permissions;
using System.Threading;
[HostProtection(SecurityAction.LinkDemand, Synchronization=true, ExternalThreading=true)]
public class ReaderWriterLockSlim : IDisposable
{
private bool fIsReentrant;
private bool fNoWaiters;
private bool fUpgradeThreadHoldingRead;
private const int hashTableSize = 0xff;
private const int LockSleep0Count = 5;
private const int LockSpinCount = 10;
private const int LockSpinCycles = 20;
private const uint MAX_READER = 0xffffffe;
private const int MaxSpinCount = 20;
private int myLock;
private uint numReadWaiters;
private uint numUpgradeWaiters;
private uint numWriteUpgradeWaiters;
private uint numWriteWaiters;
private uint owners;
private const uint READER_MASK = 0xfffffff;
private EventWaitHandle readEvent;
private ReaderWriterCount[] rwc;
private EventWaitHandle upgradeEvent;
private int upgradeLockOwnerId;
private const uint WAITING_UPGRADER = 0x20000000;
private const uint WAITING_WRITERS = 0x40000000;
private EventWaitHandle waitUpgradeEvent;
private EventWaitHandle writeEvent;
private int writeLockOwnerId;
private const uint WRITER_HELD = 0x80000000;
public ReaderWriterLockSlim() : this(LockRecursionPolicy.NoRecursion)
{
}
public ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy)
{
if (recursionPolicy == LockRecursionPolicy.SupportsRecursion)
{
this.fIsReentrant = true;
}
this.InitializeThreadCounts();
}
private void ClearUpgraderWaiting()
{
this.owners &= 0xdfffffff;
}
private void ClearWriterAcquired()
{
this.owners &= 0x7fffffff;
}
private void ClearWritersWaiting()
{
this.owners &= 0xbfffffff;
}
public void Dispose()
{
this.Dispose(true);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (this.writeEvent != null)
{
this.writeEvent.Close();
this.writeEvent = null;
}
if (this.readEvent != null)
{
this.readEvent.Close();
this.readEvent = null;
}
if (this.upgradeEvent != null)
{
this.upgradeEvent.Close();
this.upgradeEvent = null;
}
if (this.waitUpgradeEvent != null)
{
this.waitUpgradeEvent.Close();
this.waitUpgradeEvent = null;
}
}
}
private void EnterMyLock()
{
if (Interlocked.CompareExchange(ref this.myLock, 1, 0) != 0)
{
this.EnterMyLockSpin();
}
}
private void EnterMyLockSpin()
{
int num = Environment.get_ProcessorCount();
int num2 = 0;
while (true)
{
if ((num2 < 10) && (num > 1))
{
Thread.SpinWait(20 * (num2 + 1));
}
else if (num2 < 15)
{
Thread.Sleep(0);
}
else
{
Thread.Sleep(1);
}
if ((this.myLock == 0) && (Interlocked.CompareExchange(ref this.myLock, 1, 0) == 0))
{
return;
}
num2++;
}
}
public void EnterReadLock()
{
this.TryEnterReadLock(-1);
}
public void EnterUpgradeableReadLock()
{
this.TryEnterUpgradeableReadLock(-1);
}
public void EnterWriteLock()
{
this.TryEnterWriteLock(-1);
}
private void ExitAndWakeUpAppropriateWaiters()
{
if (this.fNoWaiters)
{
this.ExitMyLock();
}
else
{
this.ExitAndWakeUpAppropriateWaitersPreferringWriters();
}
}
private void ExitAndWakeUpAppropriateWaitersPreferringWriters()
{
bool flag = false;
bool flag2 = false;
uint numReaders = this.GetNumReaders();
if ((this.fIsReentrant && (this.numWriteUpgradeWaiters > 0)) && (this.fUpgradeThreadHoldingRead && (numReaders == 2)))
{
this.ExitMyLock();
this.waitUpgradeEvent.Set();
}
else if ((numReaders == 1) && (this.numWriteUpgradeWaiters > 0))
{
this.ExitMyLock();
this.waitUpgradeEvent.Set();
}
else if ((numReaders == 0) && (this.numWriteWaiters > 0))
{
this.ExitMyLock();
this.writeEvent.Set();
}
else if (numReaders >= 0)
{
if ((this.numReadWaiters == 0) && (this.numUpgradeWaiters == 0))
{
this.ExitMyLock();
}
else
{
if (this.numReadWaiters != 0)
{
flag2 = true;
}
if ((this.numUpgradeWaiters != 0) && (this.upgradeLockOwnerId == -1))
{
flag = true;
}
this.ExitMyLock();
if (flag2)
{
this.readEvent.Set();
}
if (flag)
{
this.upgradeEvent.Set();
}
}
}
else
{
this.ExitMyLock();
}
}
private void ExitMyLock()
{
this.myLock = 0;
}
public void ExitReadLock()
{
int id = Thread.CurrentThread.get_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 void ExitUpgradeableReadLock()
{
int id = Thread.CurrentThread.get_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.get_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();
}
private uint GetNumReaders()
{
return (this.owners & 0xfffffff);
}
private ReaderWriterCount GetThreadRWCount(int id, bool DontAllocate)
{
ReaderWriterCount rwc;
int index = id & 0xff;
ReaderWriterCount count2 = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -