Skip to content

Commit 68bdd2b

Browse files
committed
Added separate pool
1 parent 30c7997 commit 68bdd2b

File tree

5 files changed

+80
-42
lines changed

5 files changed

+80
-42
lines changed

src/AsyncKeyLock/AsyncKeyLock.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<Authors>usercode</Authors>
88
<Version>1.0.0</Version>
99
<PackageProjectUrl>https://github.com/usercode/AsyncKeyLock</PackageProjectUrl>
10-
<Description>Async Key-based Reader Writer Lock</Description>
10+
<Description>Async Key-based Reader Writer Lock with Cancellation Support</Description>
1111
<PublishRepositoryUrl>true</PublishRepositoryUrl>
1212
<PackageIcon>logo.png</PackageIcon>
1313
<PackageLicenseExpression>MIT</PackageLicenseExpression>

src/AsyncKeyLock/AsyncLock.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,13 @@ public Task<AsyncLockReleaser> WriterLockAsync(CancellationToken cancellation =
119119
}
120120
}
121121

122-
internal void Release(AsyncLockType type, bool sendReleasedEvent = true)
122+
internal void Release(AsyncLockReleaser releaser, bool sendReleasedEvent = true)
123123
{
124124
lock (_syncObj)
125125
{
126126
try
127127
{
128-
if (type == AsyncLockType.Write)
128+
if (releaser.Type == AsyncLockType.Write)
129129
{
130130
WriterRelease();
131131
}

src/AsyncKeyLock/AsyncLockReleaser.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,29 @@ namespace AsyncKeyLock;
99
/// </summary>
1010
public sealed class AsyncLockReleaser : IDisposable
1111
{
12-
private readonly AsyncLock _asyncLock;
13-
private readonly AsyncLockType _type;
14-
private readonly bool _lockAcquiredImmediately;
12+
private bool _disposed;
1513

16-
internal AsyncLockReleaser(AsyncLock asyncLock, AsyncLockType type, bool lockAcquiredImmediately)
17-
{
18-
_asyncLock = asyncLock;
19-
_type = type;
20-
_lockAcquiredImmediately = lockAcquiredImmediately;
21-
}
14+
/// <summary>
15+
/// AsyncLock
16+
/// </summary>
17+
private AsyncLock AsyncLock { get; }
2218

2319
/// <summary>
2420
/// Type
2521
/// </summary>
26-
public AsyncLockType Type => _type;
22+
public AsyncLockType Type { get; }
2723

2824
/// <summary>
2925
/// IsAcquiredImmediately
3026
/// </summary>
31-
public bool IsAcquiredImmediately => _lockAcquiredImmediately;
27+
public bool IsAcquiredImmediately { get; }
3228

33-
private bool _disposed;
29+
internal AsyncLockReleaser(AsyncLock asyncLock, AsyncLockType type, bool lockAcquiredImmediately)
30+
{
31+
AsyncLock = asyncLock;
32+
Type = type;
33+
IsAcquiredImmediately = lockAcquiredImmediately;
34+
}
3435

3536
public void Dispose()
3637
{
@@ -39,7 +40,7 @@ public void Dispose()
3940
return;
4041
}
4142

42-
_asyncLock.Release(_type);
43+
AsyncLock.Release(this);
4344

4445
_disposed = true;
4546

src/AsyncKeyLock/AsyncLock~.cs

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ public sealed class AsyncLock<TKey>
1212
{
1313
public AsyncLock(int maxPoolSize = 64)
1414
{
15-
MaxPoolSize = maxPoolSize;
15+
_pool = new Pool<AsyncLock>(maxPoolSize);
1616
}
1717

1818
private readonly IDictionary<TKey, AsyncLock> _locks = new Dictionary<TKey, AsyncLock>();
19-
private readonly IList<AsyncLock> _pool = new List<AsyncLock>();
20-
private readonly int MaxPoolSize;
19+
private readonly Pool<AsyncLock> _pool;
2120

2221
/// <summary>
2322
/// GetAsyncLock
@@ -28,34 +27,25 @@ private AsyncLock GetAsyncLock(TKey key)
2827
{
2928
if (_locks.TryGetValue(key, out AsyncLock? asyncLock) == false)
3029
{
31-
//is idle AsyncLock available
32-
if (_pool.Count > 0)
33-
{
34-
int lastPos = _pool.Count - 1;
35-
36-
asyncLock = _pool[lastPos];
37-
38-
_pool.RemoveAt(lastPos);
39-
}
40-
else
41-
{
42-
//create new AsyncLock
43-
asyncLock = new AsyncLock(_locks);
44-
asyncLock.Released += x =>
30+
//create new AsyncLock
31+
_pool.GetOrCreate(out asyncLock,
32+
() =>
4533
{
46-
//is AsyncLock idle
47-
if (x.State == AsyncLockState.Idle)
34+
AsyncLock a = new AsyncLock(_locks);
35+
a.Released += x =>
4836
{
49-
_locks.Remove(key);
50-
51-
//add idle AsynLock to pool
52-
if (_pool.Count < MaxPoolSize)
37+
//is AsyncLock idle
38+
if (x.State == AsyncLockState.Idle)
5339
{
40+
_locks.Remove(key);
41+
42+
//add idle AsynLock to pool
5443
_pool.Add(x);
5544
}
56-
}
57-
};
58-
}
45+
};
46+
47+
return a;
48+
});
5949

6050
_locks.Add(key, asyncLock);
6151
}

src/AsyncKeyLock/Pool.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
namespace AsyncKeyLock;
2+
3+
/// <summary>
4+
/// Pool
5+
/// </summary>
6+
internal sealed class Pool<T>
7+
{
8+
private readonly IList<T> _pool = new List<T>();
9+
private readonly int MaxPoolSize;
10+
11+
public Pool(int maxPoolSize = 64)
12+
{
13+
MaxPoolSize = maxPoolSize;
14+
}
15+
16+
public bool Add(T obj)
17+
{
18+
if (_pool.Count < MaxPoolSize)
19+
{
20+
_pool.Add(obj);
21+
22+
return true;
23+
}
24+
25+
return false;
26+
}
27+
28+
public bool GetOrCreate(out T result, Func<T> factory)
29+
{
30+
if (_pool.Count > 0)
31+
{
32+
int lastPos = _pool.Count - 1;
33+
34+
result = _pool[lastPos];
35+
36+
_pool.RemoveAt(lastPos);
37+
38+
return true;
39+
}
40+
else
41+
{
42+
result = factory();
43+
44+
return false;
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)