Skip to content

Commit

Permalink
Fixed rare race condition (thanks for pointing it out Theodor Zoulias…
Browse files Browse the repository at this point in the history
…), added limit to avoid unnecessary attempts to fill pool when initialFill > capacity.
  • Loading branch information
MarkCiliaVincenti committed Dec 29, 2022
1 parent 8af2c93 commit 825c673
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 16 deletions.
12 changes: 0 additions & 12 deletions AsyncKeyedLock.Tests/OriginalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,7 @@ public async Task BasicTestGenerics()
var key = Convert.ToInt32(Math.Ceiling((double)i / concurrency));
using (await asyncKeyedLocker.LockAsync(key))
{
await Task.Delay(20);
concurrentQueue.Enqueue((true, key));
await Task.Delay(80);
concurrentQueue.Enqueue((false, key));
}
});
Expand Down Expand Up @@ -170,9 +168,7 @@ public async Task BasicTestGenericsPooling50k()
var key = Convert.ToInt32(Math.Ceiling((double)i / concurrency));
using (await asyncKeyedLocker.LockAsync(key))
{
await Task.Delay(20);
concurrentQueue.Enqueue((true, key));
await Task.Delay(80);
concurrentQueue.Enqueue((false, key));
}
});
Expand Down Expand Up @@ -226,9 +222,7 @@ public async Task BasicTestGenericsPooling50kUnfilled()
var key = Convert.ToInt32(Math.Ceiling((double)i / concurrency));
using (await asyncKeyedLocker.LockAsync(key))
{
await Task.Delay(20);
concurrentQueue.Enqueue((true, key));
await Task.Delay(80);
concurrentQueue.Enqueue((false, key));
}
});
Expand Down Expand Up @@ -278,9 +272,7 @@ public async Task BasicTestGenericsPoolingProcessorCount()
var key = Convert.ToInt32(Math.Ceiling((double)i / concurrency));
using (await asyncKeyedLocker.LockAsync(key))
{
await Task.Delay(20);
concurrentQueue.Enqueue((true, key));
await Task.Delay(80);
concurrentQueue.Enqueue((false, key));
}
});
Expand Down Expand Up @@ -330,9 +322,7 @@ public async Task BasicTestGenericsPooling10k()
var key = Convert.ToInt32(Math.Ceiling((double)i / concurrency));
using (await asyncKeyedLocker.LockAsync(key))
{
await Task.Delay(20);
concurrentQueue.Enqueue((true, key));
await Task.Delay(80);
concurrentQueue.Enqueue((false, key));
}
});
Expand Down Expand Up @@ -382,9 +372,7 @@ public async Task BasicTestGenericsString()
var key = Convert.ToInt32(Math.Ceiling((double)i / 5)).ToString();
using (await asyncKeyedLocker.LockAsync(key))
{
await Task.Delay(20);
concurrentQueue.Enqueue((true, key));
await Task.Delay(80);
concurrentQueue.Enqueue((false, key));
}
});
Expand Down
8 changes: 4 additions & 4 deletions AsyncKeyedLock/AsyncKeyedLock.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
<PackageProjectUrl>https://github.com/MarkCiliaVincenti/AsyncKeyedLock</PackageProjectUrl>
<Copyright>MIT</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>6.0.2</Version>
<Version>6.0.3</Version>
<PackageIcon>logo.png</PackageIcon>
<PackageReleaseNotes>Fixed critical parameter validation issue, optimizations on timeouts, added out parameters for synchronous locks with timeouts, improved tests.</PackageReleaseNotes>
<PackageReleaseNotes>Fixed rare race condition (thanks for pointing it out Theodor Zoulias), added limit to avoid unnecessary attempts to fill pool when initialFill > capacity.</PackageReleaseNotes>
<Description>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.</Description>
<Copyright>© 2022 Mark Cilia Vincenti</Copyright>
<PackageTags>async,lock,key,keyed,semaphore,dictionary,pooling,duplicate,synchronization</PackageTags>
<RepositoryType>git</RepositoryType>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<AssemblyVersion>6.0.2.0</AssemblyVersion>
<FileVersion>6.0.2.0</FileVersion>
<AssemblyVersion>6.0.3.0</AssemblyVersion>
<FileVersion>6.0.3.0</FileVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
<IsPackable>true</IsPackable>
<IsTrimmable>true</IsTrimmable>
Expand Down
1 change: 1 addition & 0 deletions AsyncKeyedLock/AsyncKeyedLockPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public AsyncKeyedLockReleaser<TKey> GetObject(TKey key)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PutObject(AsyncKeyedLockReleaser<TKey> item)
{
item.ReferenceCount = 1;
_objects.TryAdd(item);
}
}
Expand Down
5 changes: 5 additions & 0 deletions AsyncKeyedLock/AsyncKeyedLockReleaser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ internal bool TryIncrement()
{
if (Monitor.TryEnter(this))
{
if (_referenceCount == 0) // rare race condition
{
Monitor.Exit(this);
return false;
}
++_referenceCount;
Monitor.Exit(this);
return true;
Expand Down

0 comments on commit 825c673

Please sign in to comment.