LockAcquisition
Provides a set of methods to acquire different types of lock.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
namespace DotNext.Threading
{
public static class LockAcquisition
{
private sealed class ReaderWriterLockSlimWithRecursion : ReaderWriterLockSlim
{
public ReaderWriterLockSlimWithRecursion()
: base(LockRecursionPolicy.SupportsRecursion)
{
}
}
private static readonly UserDataSlot<ReaderWriterLockSlim> ReaderWriterLock = UserDataSlot<ReaderWriterLockSlim>.Allocate();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ReaderWriterLockSlim GetReaderWriterLock<T>(this T obj) where T : class
{
if (obj == null)
throw new ArgumentNullException("obj");
ReaderWriterLockSlim readerWriterLockSlim = obj as ReaderWriterLockSlim;
if (readerWriterLockSlim != null)
return readerWriterLockSlim;
if (obj is SemaphoreSlim || obj is WaitHandle || obj is ReaderWriterLock)
throw new ArgumentException(ExceptionMessages.UnsupportedLockAcquisition, "obj");
return obj.GetUserData().GetOrSet<ReaderWriterLockSlim, ReaderWriterLockSlimWithRecursion>(ReaderWriterLock);
}
public static Lock.Holder AcquireReadLock<T>(this T obj) where T : class
{
return Lock.ReadLock(obj.GetReaderWriterLock(), false).Acquire();
}
public static Lock.Holder AcquireReadLock<T>(this T obj, TimeSpan timeout) where T : class
{
return Lock.ReadLock(obj.GetReaderWriterLock(), false).Acquire(timeout);
}
public static Lock.Holder AcquireWriteLock<T>(this T obj) where T : class
{
return Lock.WriteLock(obj.GetReaderWriterLock()).Acquire();
}
public static Lock.Holder AcquireWriteLock<T>(this T obj, TimeSpan timeout) where T : class
{
return Lock.WriteLock(obj.GetReaderWriterLock()).Acquire(timeout);
}
public static Lock.Holder AcquireUpgradeableReadLock<T>(this T obj) where T : class
{
return Lock.ReadLock(obj.GetReaderWriterLock(), true).Acquire();
}
public static Lock.Holder AcquireUpgradeableReadLock<T>(this T obj, TimeSpan timeout) where T : class
{
return Lock.ReadLock(obj.GetReaderWriterLock(), true).Acquire(timeout);
}
}
}