Use DigestableSafeMutexIoManager for TransactionsFileManager
MODIFY
WalletWasabi.Tests/UnitTests/IoTests.cs
WalletWasabi.Tests/UnitTests/IoTests.cs
@@ -153,10 +153,10 @@ namespace WalletWasabi.Tests.UnitTests
await Task.Run(async () =>
{
- using (await ioman1.Mutex.LockAsync())
+ using (await ioman1.AsyncLock.LockAsync())
{
// Should not be a problem because they use different Mutexes.
- using (await ioman2.Mutex.LockAsync())
+ using (await ioman2.AsyncLock.LockAsync())
{
await ioman1.WriteAllLinesAsync(lines);
await ioman2.WriteAllLinesAsync(lines);
@@ -221,7 +221,7 @@ namespace WalletWasabi.Tests.UnitTests
{
list.Add(next);
}
- using (await ioman.Mutex.LockAsync())
+ using (await ioman.AsyncLock.LockAsync())
{
var lines = (await ioman.ReadAllLinesAsync()).ToList();
lines.Add(next);

MODIFY
WalletWasabi/Blockchain/Transactions/TransactionStore.cs
WalletWasabi/Blockchain/Transactions/TransactionStore.cs
@@ -18,7 +18,7 @@ namespace WalletWasabi.Blockchain.Transactions
private Dictionary<uint256, SmartTransaction> Transactions { get; set; }
private object TransactionsLock { get; set; }
- private MutexIoManager TransactionsFileManager { get; set; }
+ private DigestableSafeMutexIoManager TransactionsFileManager { get; set; }
private List<ITxStoreOperation> Operations { get; } = new List<ITxStoreOperation>();
private object OperationsLock { get; } = new object();
@@ -35,9 +35,9 @@ namespace WalletWasabi.Blockchain.Transactions
var fileName = Path.Combine(WorkFolderPath, "Transactions.dat");
var transactionsFilePath = Path.Combine(WorkFolderPath, fileName);
- TransactionsFileManager = new MutexIoManager(transactionsFilePath);
+ TransactionsFileManager = new DigestableSafeMutexIoManager(transactionsFilePath);
- using (await TransactionsFileManager.Mutex.LockAsync().ConfigureAwait(false))
+ using (await TransactionsFileManager.AsyncLock.LockAsync().ConfigureAwait(false))
{
IoHelpers.EnsureDirectoryExists(WorkFolderPath);
@@ -305,7 +305,7 @@ namespace WalletWasabi.Blockchain.Transactions
}
}
- using (await TransactionsFileManager.Mutex.LockAsync().ConfigureAwait(false))
+ using (await TransactionsFileManager.AsyncLock.LockAsync().ConfigureAwait(false))
{
foreach (ITxStoreOperation op in operationsToExecute)
{

MODIFY
WalletWasabi/Io/IoManager.cs
WalletWasabi/Io/IoManager.cs
@@ -8,7 +8,7 @@ using WalletWasabi.Helpers;
namespace WalletWasabi.Io
{
- public class IoManager
+ public abstract class IoManager
{
public IoManager(string filePath)
{

MODIFY
WalletWasabi/Io/MutexIoManager.cs
WalletWasabi/Io/MutexIoManager.cs
@@ -3,24 +3,13 @@ using WalletWasabi.Crypto;
namespace WalletWasabi.Io
{
- public class MutexIoManager : IoManager
+ public abstract class MutexIoManager : IoManager
{
public MutexIoManager(string filePath) : base(filePath)
{
- var shortHash = HashHelpers.GenerateSha256Hash(FilePath).Substring(0, 7);
-
- // https://docs.microsoft.com/en-us/dotnet/api/system.threading.mutex?view=netframework-4.8
- // On a server that is running Terminal Services, a named system mutex can have two levels of visibility.
- // If its name begins with the prefix "Global\", the mutex is visible in all terminal server sessions.
- // If its name begins with the prefix "Local\", the mutex is visible only in the terminal server session where it was created.
- // In that case, a separate mutex with the same name can exist in each of the other terminal server sessions on the server.
- // If you do not specify a prefix when you create a named mutex, it takes the prefix "Local\".
- // Within a terminal server session, two mutexes whose names differ only by their prefixes are separate mutexes,
- // and both are visible to all processes in the terminal server session.
- // That is, the prefix names "Global\" and "Local\" describe the scope of the mutex name relative to terminal server sessions, not relative to processes.
- Mutex = new AsyncMutex($"{FileNameWithoutExtension}-{shortHash}");
+ AsyncLock = new AsyncLock();
}
- public AsyncMutex Mutex { get; }
+ public AsyncLock AsyncLock { get; }
}
}

MODIFY
WalletWasabi/Stores/IndexStore.cs
WalletWasabi/Stores/IndexStore.cs
@@ -64,8 +64,8 @@ namespace WalletWasabi.Stores
IndexLock = new AsyncLock();
using (await IndexLock.LockAsync().ConfigureAwait(false))
- using (await MatureIndexFileManager.Mutex.LockAsync().ConfigureAwait(false))
- using (await ImmatureIndexFileManager.Mutex.LockAsync().ConfigureAwait(false))
+ using (await MatureIndexFileManager.AsyncLock.LockAsync().ConfigureAwait(false))
+ using (await ImmatureIndexFileManager.AsyncLock.LockAsync().ConfigureAwait(false))
{
IoHelpers.EnsureDirectoryExists(WorkFolderPath);
@@ -332,8 +332,8 @@ namespace WalletWasabi.Stores
{
Logger.LogCritical($"Deleting all filters and crashing the software...");
- using (await MatureIndexFileManager.Mutex.LockAsync(cancel).ConfigureAwait(false))
- using (await ImmatureIndexFileManager.Mutex.LockAsync(cancel).ConfigureAwait(false))
+ using (await MatureIndexFileManager.AsyncLock.LockAsync(cancel).ConfigureAwait(false))
+ using (await ImmatureIndexFileManager.AsyncLock.LockAsync(cancel).ConfigureAwait(false))
{
ImmatureIndexFileManager.DeleteMe();
MatureIndexFileManager.DeleteMe();
@@ -384,8 +384,8 @@ namespace WalletWasabi.Stores
Interlocked.Exchange(ref _throttleId, 0); // So to notify the currently throttled threads that they do not have to run.
}
- using (await MatureIndexFileManager.Mutex.LockAsync(cancel).ConfigureAwait(false))
- using (await ImmatureIndexFileManager.Mutex.LockAsync(cancel).ConfigureAwait(false))
+ using (await MatureIndexFileManager.AsyncLock.LockAsync(cancel).ConfigureAwait(false))
+ using (await ImmatureIndexFileManager.AsyncLock.LockAsync(cancel).ConfigureAwait(false))
using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
{
// Do not feed the cancellationToken here I always want this to finish running for safety.
@@ -412,7 +412,7 @@ namespace WalletWasabi.Stores
public async Task ForeachFiltersAsync(Func<FilterModel, Task> todo, Height fromHeight, CancellationToken cancel = default)
{
- using (await MatureIndexFileManager.Mutex.LockAsync(cancel).ConfigureAwait(false))
+ using (await MatureIndexFileManager.AsyncLock.LockAsync(cancel).ConfigureAwait(false))
using (await IndexLock.LockAsync(cancel).ConfigureAwait(false))
{
var firstImmatureHeight = ImmatureFilters.FirstOrDefault()?.Header?.Height;

Use DigestableSafeMutexIoManager for TransactionsFileManager