diff --git a/src/ZeroLog.Impl.Base/LogManager.cs b/src/ZeroLog.Impl.Base/LogManager.cs index 4f8aa28..3977922 100644 --- a/src/ZeroLog.Impl.Base/LogManager.cs +++ b/src/ZeroLog.Impl.Base/LogManager.cs @@ -20,6 +20,9 @@ public sealed partial class LogManager /// /// The type. public static Log GetLogger() +#if NET9_0_OR_GREATER + where T : allows ref struct +#endif => GetLogger(typeof(T)); /// diff --git a/src/ZeroLog.Impl.Full/BufferSegmentProvider.cs b/src/ZeroLog.Impl.Full/BufferSegmentProvider.cs index cb4b000..ffb19dc 100644 --- a/src/ZeroLog.Impl.Full/BufferSegmentProvider.cs +++ b/src/ZeroLog.Impl.Full/BufferSegmentProvider.cs @@ -4,7 +4,11 @@ namespace ZeroLog; internal unsafe class BufferSegmentProvider { - private readonly object _lock = new(); +#if NET9_0_OR_GREATER + private static readonly System.Threading.Lock _lock = new(); +#else + private static readonly object _lock = new(); +#endif private readonly int _segmentCount; private readonly int _segmentSize; diff --git a/src/ZeroLog.Impl.Full/Runner.cs b/src/ZeroLog.Impl.Full/Runner.cs index 42d1473..754ae96 100644 --- a/src/ZeroLog.Impl.Full/Runner.cs +++ b/src/ZeroLog.Impl.Full/Runner.cs @@ -310,7 +310,11 @@ public override void Flush() internal sealed class SyncRunner(ZeroLogConfiguration config) : Runner(config) { - private readonly object _lock = new(); +#if NET9_0_OR_GREATER + private static readonly Lock _lock = new(); +#else + private static readonly object _lock = new(); +#endif public override void Submit(LogMessage message) { diff --git a/src/ZeroLog.Impl.Full/UnmanagedCache.cs b/src/ZeroLog.Impl.Full/UnmanagedCache.cs index a1bfab3..9a73f40 100644 --- a/src/ZeroLog.Impl.Full/UnmanagedCache.cs +++ b/src/ZeroLog.Impl.Full/UnmanagedCache.cs @@ -31,6 +31,12 @@ internal delegate bool FormatterDelegate( ZeroLogConfiguration config ); +#if NET9_0_OR_GREATER + private static readonly System.Threading.Lock _lock = new(); +#else + private static readonly object _lock = new(); +#endif + private static readonly Dictionary _unmanagedStructs = new(); private static readonly MethodInfo _registerMethod = typeof(UnmanagedCache).GetMethod(nameof(Register), Type.EmptyTypes)!; @@ -52,7 +58,7 @@ public static void Register(UnmanagedFormatterDelegate formatter) { ArgumentNullException.ThrowIfNull(formatter); - lock (_unmanagedStructs) + lock (_lock) { _unmanagedStructs[typeof(T).TypeHandle.Value] = (byte* valuePtr, Span destination, out int charsWritten, ReadOnlySpan format, ZeroLogConfiguration _) => FormatterGeneric(valuePtr, destination, out charsWritten, format, formatter); @@ -109,7 +115,7 @@ private static bool FormatterGenericNullable(byte* valuePtr, public static bool TryGetFormatter(IntPtr typeHandle, out FormatterDelegate formatter) { // This is accessed from a single thread, there should be no contention - lock (_unmanagedStructs) + lock (_lock) { return _unmanagedStructs.TryGetValue(typeHandle, out formatter!); } diff --git a/src/ZeroLog.Tests/PerformanceTests.cs b/src/ZeroLog.Tests/PerformanceTests.cs index 59ecf01..9c60de9 100644 --- a/src/ZeroLog.Tests/PerformanceTests.cs +++ b/src/ZeroLog.Tests/PerformanceTests.cs @@ -55,7 +55,7 @@ public void should_run_test() var signal = _testAppender.SetMessageCountTarget(totalMessageCount); var utcNow = DateTime.UtcNow; - Parallel.For(0, threadCount, i => + Parallel.For(0, threadCount, _ => { for (var k = 0; k < threadMessageCount; k++) { diff --git a/src/ZeroLog.Tests/Support/AssertExtensions.cs b/src/ZeroLog.Tests/Support/AssertExtensions.cs index 5bffecb..3e8cee4 100644 --- a/src/ZeroLog.Tests/Support/AssertExtensions.cs +++ b/src/ZeroLog.Tests/Support/AssertExtensions.cs @@ -7,6 +7,9 @@ namespace ZeroLog.Tests.Support; #nullable enable +#if NET6_0_OR_GREATER +[System.Diagnostics.StackTraceHidden] +#endif internal static class AssertExtensions { public static void ShouldEqual(this T? actual, T? expected)