From cd6d9f9343f91c47a251df51703d67a80519b326 Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Mon, 2 Jan 2023 08:50:55 +0100 Subject: [PATCH] Minor optimizations. --- AsyncKeyedLock/AsyncKeyedLock.csproj | 8 +++---- AsyncKeyedLock/AsyncKeyedLockDictionary.cs | 27 ++++++++-------------- AsyncKeyedLock/AsyncKeyedLockPool.cs | 6 ++--- AsyncKeyedLock/AsyncKeyedLockReleaser.cs | 8 ++++--- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/AsyncKeyedLock/AsyncKeyedLock.csproj b/AsyncKeyedLock/AsyncKeyedLock.csproj index bf24ed5..ed3f6ec 100644 --- a/AsyncKeyedLock/AsyncKeyedLock.csproj +++ b/AsyncKeyedLock/AsyncKeyedLock.csproj @@ -8,16 +8,16 @@ https://github.com/MarkCiliaVincenti/AsyncKeyedLock MIT MIT - 6.0.4 + 6.0.5 logo.png Optimizations and fixing of more rare race conditions. An asynchronous .NET Standard 2.0 library that allows you to lock based on a key (keyed semaphores), limiting concurrent threads sharing the same key to a specified number. - © 2022 Mark Cilia Vincenti + © 2023 Mark Cilia Vincenti async,lock,key,keyed,semaphore,dictionary,pooling,duplicate,synchronization git false - 6.0.4.0 - 6.0.4.0 + 6.0.4.1 + 6.0.4.1 README.md true true diff --git a/AsyncKeyedLock/AsyncKeyedLockDictionary.cs b/AsyncKeyedLock/AsyncKeyedLockDictionary.cs index 122ae03..c72cb30 100644 --- a/AsyncKeyedLock/AsyncKeyedLockDictionary.cs +++ b/AsyncKeyedLock/AsyncKeyedLockDictionary.cs @@ -102,7 +102,7 @@ public AsyncKeyedLockReleaser GetOrAdd(TKey key) } if (releaser.TryIncrement(key)) { - releaser.IsPooled = true; + releaser.IsNotInUse = true; _pool.PutObject(releaserToAdd); return releaser; } @@ -135,24 +135,20 @@ public void Release(AsyncKeyedLockReleaser releaser) { Monitor.Enter(releaser); - if (--releaser.ReferenceCount == 0) + if (releaser.ReferenceCount == 1) { TryRemove(releaser.Key, out _); + releaser.IsNotInUse = true; + Monitor.Exit(releaser); if (PoolingEnabled) { - releaser.IsPooled = true; - Monitor.Exit(releaser); - releaser.ReferenceCount = 1; _pool.PutObject(releaser); } - else - { - Monitor.Exit(releaser); - } releaser.SemaphoreSlim.Release(); return; } + --releaser.ReferenceCount; Monitor.Exit(releaser); releaser.SemaphoreSlim.Release(); } @@ -162,23 +158,18 @@ public void ReleaseWithoutSemaphoreRelease(AsyncKeyedLockReleaser releaser { Monitor.Enter(releaser); - if (--releaser.ReferenceCount == 0) + if (releaser.ReferenceCount == 1) { TryRemove(releaser.Key, out _); + releaser.IsNotInUse = true; + Monitor.Exit(releaser); if (PoolingEnabled) { - releaser.IsPooled = true; - Monitor.Exit(releaser); - releaser.ReferenceCount = 1; _pool.PutObject(releaser); } - else - { - Monitor.Exit(releaser); - } return; } - + --releaser.ReferenceCount; Monitor.Exit(releaser); } } diff --git a/AsyncKeyedLock/AsyncKeyedLockPool.cs b/AsyncKeyedLock/AsyncKeyedLockPool.cs index d963b47..6450338 100644 --- a/AsyncKeyedLock/AsyncKeyedLockPool.cs +++ b/AsyncKeyedLock/AsyncKeyedLockPool.cs @@ -18,7 +18,7 @@ public AsyncKeyedLockPool(Func> objectGenerat for (int i = 0; i < capacity; ++i) { var releaser = _objectGenerator(default); - releaser.IsPooled = true; + releaser.IsNotInUse = true; _objects.Add(releaser); } } @@ -28,7 +28,7 @@ public AsyncKeyedLockPool(Func> objectGenerat for (int i = 0; i < initialFill; ++i) { var releaser = _objectGenerator(default); - releaser.IsPooled = true; + releaser.IsNotInUse = true; _objects.Add(releaser); } } @@ -40,7 +40,7 @@ public AsyncKeyedLockReleaser GetObject(TKey key) if (_objects.TryTake(out var item)) { item.Key = key; - item.IsPooled = false; + item.IsNotInUse = false; return item; } return _objectGenerator(key); diff --git a/AsyncKeyedLock/AsyncKeyedLockReleaser.cs b/AsyncKeyedLock/AsyncKeyedLockReleaser.cs index 6917b43..86d9ab9 100644 --- a/AsyncKeyedLock/AsyncKeyedLockReleaser.cs +++ b/AsyncKeyedLock/AsyncKeyedLockReleaser.cs @@ -9,7 +9,7 @@ namespace AsyncKeyedLock /// public sealed class AsyncKeyedLockReleaser : IDisposable { - internal bool IsPooled { get; set; } = false; + internal bool IsNotInUse { get; set; } = false; private TKey _key; @@ -54,7 +54,7 @@ internal bool TryIncrement(TKey key) { if (Monitor.TryEnter(this)) { - if (IsPooled || !_key.Equals(key)) // rare race condition + if (IsNotInUse || !_key.Equals(key)) // rare race condition { Monitor.Exit(this); return false; @@ -71,7 +71,7 @@ internal bool TryIncrementNoPooling() { if (Monitor.TryEnter(this)) { - if (_referenceCount == 0) // rare race condition + if (IsNotInUse) // rare race condition { Monitor.Exit(this); return false; @@ -86,11 +86,13 @@ internal bool TryIncrementNoPooling() /// /// Releases the object once. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { _dictionary.Release(this); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Dispose(bool enteredSemaphore) { if (enteredSemaphore)