Use asynclock in asyncmutex
MODIFY
WalletWasabi.Tests/StoreTests.cs
WalletWasabi.Tests/StoreTests.cs
@@ -119,6 +119,35 @@ namespace WalletWasabi.Tests
var num = numbers[i];
Assert.Equal(prevnum + 1, num);
}
+
+ var mutex = new AsyncMutex("foo");
+ using (await mutex.LockAsync())
+ {
+ using (var cts = new CancellationTokenSource(100))
+ {
+ await Assert.ThrowsAsync<IOException>(async () =>
+ {
+ using (await mutex.LockAsync(cts.Token))
+ {
+ }
+ });
+ }
+ }
+
+ //var mutex = new AsyncMutex("foo");
+ //using (await mutex.LockAsync())
+ //{
+ // using (var cts = new CancellationTokenSource(100))
+ // {
+ // var mutex2 = new AsyncMutex("foo");
+ // await Assert.ThrowsAsync<IOException>(async () =>
+ // {
+ // using (await mutex2.LockAsync(cts.Token))
+ // {
+ // }
+ // });
+ // }
+ //}
}
[Fact]

MODIFY
WalletWasabi/Nito/AsyncEx/AsyncMutex.cs
WalletWasabi/Nito/AsyncEx/AsyncMutex.cs
@@ -15,7 +15,7 @@ namespace Nito.AsyncEx
private string FullName { get; set; }
private Mutex Mutex { get; set; }
- private int _isMutexInitialized;
+ private AsyncLock AsyncLock { get; set; }
public AsyncMutex(string name, int pollInterval = 100)
{
@@ -31,39 +31,18 @@ namespace Nito.AsyncEx
ShortName = name;
PollInterval = pollInterval;
FullName = $"Global\\4AA0E5A2-A94F-4B92-B962-F2BBC7A68323-{name}";
- _isMutexInitialized = 0;
- }
-
- private async Task<bool> TryGetLockAsync(CancellationToken cancellationToken)
- {
- try
- {
- var start = DateTime.Now;
- while (DateTime.Now - start < TimeSpan.FromSeconds(90))
- {
- var res = Interlocked.CompareExchange(ref _isMutexInitialized, 1, 0);
- if (res == 0)
- {
- // We have the local lock.
- return true;
- }
- await Task.Delay(PollInterval, cancellationToken);
- }
- }
- catch (Exception)
- {
- return false;
- }
- return false;
+ Mutex = null;
+ AsyncLock = new AsyncLock();
}
public async Task<IDisposable> LockAsync(CancellationToken cancellationToken = default)
{
Exception inner = null;
- if (await TryGetLockAsync(cancellationToken))
- {
+
try
{
+ await AsyncLock.LockAsync(cancellationToken);
+
Mutex = new Mutex(false, FullName);
// acquire the mutex (or timeout after 60 seconds)
// will return false if it timed out
@@ -99,15 +78,17 @@ namespace Nito.AsyncEx
}
Mutex?.Dispose();
- Interlocked.Exchange(ref _isMutexInitialized, 0);
- }
+ Mutex = null;
+ AsyncLock.ReleaseLock();
+
throw new IOException($"Couldn't acquire system wide mutex on {ShortName}", inner);
}
private void ReleaseLock()
{
Mutex?.Dispose();
- Interlocked.Exchange(ref _isMutexInitialized, 0);
+ Mutex = null;
+ AsyncLock.ReleaseLock();
}
/// <summary>

Use asynclock in asyncmutex