/// <summary> /// Releases a reference to a doorman. If the ref-count hits zero, then the doorman is /// returned to the pool (or is simply left for the garbage collector to cleanup if the /// pool is already full). /// </summary> /// <param name="doorman">The <see cref="Doorman"/>.</param> private static void ReleaseDoorman(Doorman doorman) { bool lockTaken = false; try { spinLock.Enter(ref lockTaken); if (--doorman.RefCount == 0) { Keys.Remove(doorman.Key); if (Pool.Count < MaxPoolSize) { doorman.Key = null; Pool.Push(doorman); } } } finally { if (lockTaken) { spinLock.Exit(); } } }
/// <inheritdoc /> public void Dispose() { lock (Keys) { Doorman doorman = Keys[this.key]; --doorman.RefCount; if (doorman.RefCount == 0) { Keys.Remove(this.key); doorman.Reset(); DoormanPool.Return(doorman); } doorman.Semaphore.Release(); } }
/// <summary> /// Locks the current thread in write mode asynchronously. /// </summary> /// <param name="key">The key identifying the specific object to lock against.</param> /// <returns> /// The <see cref="Task{IDisposable}"/> that will release the lock. /// </returns> public async Task <IDisposable> WriterLockAsync(string key) { Doorman doorman = GetDoorman(key); return(await doorman.WriterLockAsync().ConfigureAwait(false)); }
/// <summary> /// Locks the current thread in read mode asynchronously. /// </summary> /// <param name="key">The key identifying the specific object to lock against.</param> /// <returns> /// The <see cref="Task{IDisposable}"/> that will release the lock. /// </returns> public async Task <IDisposable> ReaderLockAsync(string key) { Doorman doorman = GetDoorman(key); return(await doorman.ReaderLockAsync()); }
internal Releaser(Doorman toRelease, bool writer) { this.toRelease = toRelease; this.writer = writer; }
/// <summary> /// Returns an doorman to the pool that was previously obtained using the <see cref="Rent"></see> /// method on the same <see cref="DoormanPool"></see> instance. /// </summary> /// <param name="doorman">The doorman to return</param> public static void Return(Doorman doorman) { Guard.NotNull(doorman, nameof(doorman)); Pool.Add(doorman); }
/// <summary> /// Locks the current thread in read mode asynchronously. /// </summary> /// <param name="key">The key identifying the specific object to lock against.</param> /// <returns> /// The <see cref="Task{IDisposable}"/> that will release the lock. /// </returns> public async Task <IDisposable> ReaderLockAsync(string key) { Doorman doorman = Keys.GetOrAdd(key, GetDoorman); return(await doorman.ReaderLockAsync().ConfigureAwait(false)); }