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 static readonly UserDataSlot<ReaderWriterLockSlim> ReaderWriterLock = UserDataSlot<ReaderWriterLockSlim>.Allocate();
private static readonly Func<ReaderWriterLockSlim> ReaderWriterLockFactory = () => new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
private static Lock Acquire<T>(T obj, Converter<T, Lock> locker) where T : class
{
Lock result = locker(obj);
result.Acquire();
return result;
}
private static Lock Acquire<T>(T obj, Converter<T, Lock> locker, TimeSpan timeout) where T : class
{
Lock result = locker(obj);
if (!result.TryAcquire(timeout))
throw new TimeoutException();
return result;
}
public static Lock Lock<T>(this T obj) where T : class
{
return Acquire(obj, DotNext.Threading.Lock.Monitor);
}
public static Lock Lock<T>(this T obj, TimeSpan timeout) where T : class
{
return Acquire(obj, DotNext.Threading.Lock.Monitor, timeout);
}
public static Lock Lock(this SemaphoreSlim semaphore)
{
return Acquire(semaphore, DotNext.Threading.Lock.Semaphore);
}
public static Lock Lock(this SemaphoreSlim semaphore, TimeSpan timeout)
{
return Acquire(semaphore, DotNext.Threading.Lock.Semaphore, timeout);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ReaderWriterLockSlim GetReaderWriterLock<T>(this T obj) where T : class
{
return obj.GetUserData().GetOrSet(ReaderWriterLock, ReaderWriterLockFactory);
}
public static Lock ReadLock<T>(this T obj) where T : class
{
return obj.GetReaderWriterLock().ReadLock();
}
public static Lock ReadLock<T>(this T obj, TimeSpan timeout) where T : class
{
return obj.GetReaderWriterLock().ReadLock(timeout);
}
public static Lock ReadLock(this ReaderWriterLockSlim rwLock)
{
return Acquire(rwLock, DotNext.Threading.Lock.ReadLock);
}
public static Lock ReadLock(this ReaderWriterLockSlim rwLock, TimeSpan timeout)
{
return Acquire(rwLock, DotNext.Threading.Lock.ReadLock, timeout);
}
public static Lock WriteLock<T>(this T obj) where T : class
{
return obj.GetReaderWriterLock().WriteLock();
}
public static Lock WriteLock<T>(this T obj, TimeSpan timeout) where T : class
{
return obj.GetReaderWriterLock().WriteLock(timeout);
}
public static Lock WriteLock(this ReaderWriterLockSlim rwLock)
{
return Acquire(rwLock, DotNext.Threading.Lock.WriteLock);
}
public static Lock WriteLock(this ReaderWriterLockSlim rwLock, TimeSpan timeout)
{
return Acquire(rwLock, DotNext.Threading.Lock.WriteLock, timeout);
}
public static Lock UpgradableReadLock<T>(this T obj) where T : class
{
return obj.GetReaderWriterLock().UpgradableReadLock();
}
public static Lock UpgradableReadLock<T>(this T obj, TimeSpan timeout) where T : class
{
return obj.GetReaderWriterLock().UpgradableReadLock(timeout);
}
public static Lock UpgradableReadLock(this ReaderWriterLockSlim rwLock)
{
return Acquire(rwLock, DotNext.Threading.Lock.UpgradableReadLock);
}
public static Lock UpgradableReadLock(this ReaderWriterLockSlim rwLock, TimeSpan timeout)
{
return Acquire(rwLock, DotNext.Threading.Lock.UpgradableReadLock, timeout);
}
}
}