From: Stephen Toub Date: Tue, 15 Jun 2021 00:15:17 +0000 (-0400) Subject: Fix thread-safety of DiagnosticListener.AllListeners (#54142) X-Git-Tag: submit/tizen/20210909.063632~776 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=90c1750027a0935a40f1db85d084261ea11b0d08;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Fix thread-safety of DiagnosticListener.AllListeners (#54142) --- diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs index cd588e6..e06a927 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticListener.cs @@ -39,12 +39,10 @@ namespace System.Diagnostics #if ENABLE_HTTP_HANDLER GC.KeepAlive(HttpHandlerDiagnosticListener.s_instance); #endif - - if (s_allListenerObservable == null) - { - s_allListenerObservable = new AllListenerObservable(); - } - return s_allListenerObservable; + return + s_allListenerObservable ?? + Interlocked.CompareExchange(ref s_allListenerObservable, new AllListenerObservable(), null) ?? + s_allListenerObservable; } } @@ -137,9 +135,7 @@ namespace System.Diagnostics lock (s_allListenersLock) { // Issue the callback for this new diagnostic listener. - var allListenerObservable = s_allListenerObservable; - if (allListenerObservable != null) - allListenerObservable.OnNewDiagnosticListener(this); + s_allListenerObservable?.OnNewDiagnosticListener(this); // And add it to the list of all past listeners. _next = s_allListeners; @@ -460,7 +456,7 @@ namespace System.Diagnostics private bool _disposed; // Has Dispose been called? private static DiagnosticListener? s_allListeners; // linked list of all instances of DiagnosticListeners. - private static AllListenerObservable? s_allListenerObservable; // to make callbacks to this object when listeners come into existence. + private static volatile AllListenerObservable? s_allListenerObservable; // to make callbacks to this object when listeners come into existence. private static readonly object s_allListenersLock = new object(); #if false private static readonly DiagnosticListener s_default = new DiagnosticListener("DiagnosticListener.DefaultListener");