Improve Interlocked patterns. Fix Increment/Decrement followed by immediate Reads
Related:
MODIFY
WalletWasabi.Tests/P2pTests.cs
WalletWasabi.Tests/P2pTests.cs
@@ -167,8 +167,7 @@ namespace WalletWasabi.Tests
private void ConnectedNodes_Added(object sender, NodeEventArgs e)
{
var nodes = sender as NodesCollection;
- Interlocked.Increment(ref _nodeCount);
- if (Interlocked.Read(ref _nodeCount) == 8)
+ if (Interlocked.Increment(ref _nodeCount) == 8)
{
Logger.LogTrace<P2pTests>($"Max node count reached: {Interlocked.Read(ref _nodeCount)}.");
}
@@ -179,9 +178,9 @@ namespace WalletWasabi.Tests
private void ConnectedNodes_Removed(object sender, NodeEventArgs e)
{
var nodes = sender as NodesCollection;
- Interlocked.Decrement(ref _nodeCount);
+ var nodeCount = Interlocked.Decrement(ref _nodeCount);
// Trace is fine here, building the connections is more exciting than removing them.
- Logger.LogTrace<P2pTests>($"Node count: {Interlocked.Read(ref _nodeCount)}.");
+ Logger.LogTrace<P2pTests>($"Node count: {nodeCount}.");
}
private long _mempoolTransactionCount = 0;

MODIFY
WalletWasabi/Logging/Logger.cs
WalletWasabi/Logging/Logger.cs
@@ -24,7 +24,7 @@ namespace WalletWasabi.Logging
public static string FileEntryEncryptionPassword { get; private set; } = null;
- private static long _loggerFailed = 0;
+ private static int _loggingFailedCount = 0;
private static readonly object Lock = new object();
@@ -208,14 +208,14 @@ namespace WalletWasabi.Logging
}
catch (Exception ex)
{
- Interlocked.Increment(ref _loggerFailed);
- if (Interlocked.Read(ref _loggerFailed) > 1)
+ if (Interlocked.Increment(ref _loggingFailedCount) == 1) // If it only failed the first time, try log the failure.
{
- Interlocked.Exchange(ref _loggerFailed, 0);
- return;
- }
LogDebug($"Logging failed: {ex}", $"{nameof(Logger)}.{nameof(Logging)}.{nameof(Logger)}");
}
+ // If logging the failure is successful then clear the failure counter.
+ // If it's not the first time the logging failed, then we don't try to log logging failure, so clear the failure counter.
+ Interlocked.Exchange(ref _loggingFailedCount, 0);
+ }
}
private static void Log(LogLevel level, string message, Type category)

MODIFY
WalletWasabi/Models/ChaumianCoinJoin/CcjRound.cs
WalletWasabi/Models/ChaumianCoinJoin/CcjRound.cs
@@ -140,8 +140,7 @@ namespace WalletWasabi.Models.ChaumianCoinJoin
{
try
{
- Interlocked.Increment(ref RoundCount);
- RoundId = Interlocked.Read(ref RoundCount);
+ RoundId = Interlocked.Increment(ref RoundCount);
RpcClient = Guard.NotNull(nameof(rpc), rpc);
UtxoReferee = Guard.NotNull(nameof(utxoReferee), utxoReferee);

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -774,8 +774,7 @@ namespace WalletWasabi.Services
try
{
- Interlocked.Increment(ref _concurrentBlockDownload);
- ConcurrentBlockDownloadNumberChanged?.Invoke(this, _concurrentBlockDownload);
+ ConcurrentBlockDownloadNumberChanged?.Invoke(this, Interlocked.Increment(ref _concurrentBlockDownload));
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(64))) // 1/2 ADSL 512 kbit/s 00:00:32
{
@@ -823,8 +822,8 @@ namespace WalletWasabi.Services
}
finally
{
- Interlocked.Decrement(ref _concurrentBlockDownload);
- ConcurrentBlockDownloadNumberChanged?.Invoke(this, _concurrentBlockDownload);
+ var concurrentBlockDownload = Interlocked.Decrement(ref _concurrentBlockDownload);
+ ConcurrentBlockDownloadNumberChanged?.Invoke(this, concurrentBlockDownload);
}
break; // If got this far break, then we have the block, it's valid. Break.

Improve Interlocked patterns. Fix Increment/Decrement followed by immediate Reads
Related: https://github.com/zkSNACKs/WalletWasabi/issues/1276