diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs index 492e186b95bfc7..318a8cc768024e 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Lock.NativeAot.cs @@ -173,7 +173,7 @@ private static bool TryInitializeStatics() s_minSpinCount = DetermineMinSpinCount(); // Also initialize some types that are used later to prevent potential class construction cycles - NativeRuntimeEventSource.Log.IsEnabled(); + _ = NativeRuntimeEventSource.Log; } catch { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs index fe794fdf9426e1..056ff96d41b1ea 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Lock.cs @@ -444,9 +444,9 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) Wait: bool areContentionEventsEnabled = - NativeRuntimeEventSource.Log.IsEnabled( + NativeRuntimeEventSource.Log?.IsEnabled( EventLevel.Informational, - NativeRuntimeEventSource.Keywords.ContentionKeyword); + NativeRuntimeEventSource.Keywords.ContentionKeyword) ?? false; AutoResetEvent waitEvent = _waitEvent ?? CreateWaitEvent(areContentionEventsEnabled); if (State.TryLockBeforeWait(this)) { @@ -463,7 +463,7 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) long waitStartTimeTicks = 0; if (areContentionEventsEnabled) { - NativeRuntimeEventSource.Log.ContentionStart(this); + NativeRuntimeEventSource.Log!.ContentionStart(this); waitStartTimeTicks = Stopwatch.GetTimestamp(); } @@ -535,7 +535,7 @@ private ThreadId TryEnterSlow(int timeoutMs, ThreadId currentThreadId) { double waitDurationNs = (Stopwatch.GetTimestamp() - waitStartTimeTicks) * 1_000_000_000.0 / Stopwatch.Frequency; - NativeRuntimeEventSource.Log.ContentionStop(waitDurationNs); + NativeRuntimeEventSource.Log!.ContentionStop(waitDurationNs); } return currentThreadId; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.cs index 7d78f3aea97cb7..58b5d8341414b3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/WaitHandle.cs @@ -132,6 +132,12 @@ internal bool WaitOneNoCheck( #if !CORECLR // CoreCLR sends the wait events from the native side bool sendWaitEvents = millisecondsTimeout != 0 && +#if NATIVEAOT + // A null check is necessary in NativeAOT due to the possibility of reentrance during class + // construction, as this path can be reached through Lock. See + // https://github.com/dotnet/runtime/issues/94728 for a call stack. + NativeRuntimeEventSource.Log != null && +#endif NativeRuntimeEventSource.Log.IsEnabled( EventLevel.Verbose, NativeRuntimeEventSource.Keywords.WaitHandleKeyword);