55using System . Collections . Generic ;
66using System . Globalization ;
77using System . IO ;
8+ using System . Threading ;
89
910namespace Microsoft . DebugEngineHost
1011{
@@ -15,7 +16,7 @@ public static class HostLogger
1516
1617 private static string s_engineLogFile ;
1718
18- private static readonly FeedbackLogBuffer s_circularBuffer = new FeedbackLogBuffer ( ) ;
19+ private static FeedbackLogBuffer s_circularBuffer ;
1920 private static VSFeedbackLogger s_feedbackLogger ;
2021
2122 public static void EnableHostLogging ( Action < string > callback , LogLevel level = LogLevel . Verbose )
@@ -27,7 +28,7 @@ public static void EnableHostLogging(Action<string> callback, LogLevel level = L
2728
2829 if ( s_feedbackLogger == null )
2930 {
30- s_feedbackLogger = new VSFeedbackLogger ( s_circularBuffer ) ;
31+ s_feedbackLogger = new VSFeedbackLogger ( EnsureFeedbackBuffer ( ) ) ;
3132 }
3233 }
3334
@@ -59,6 +60,14 @@ public static ILogChannel GetNatvisLogChannel()
5960 return s_natvisLogChannel ;
6061 }
6162
63+ /// <summary>
64+ /// Returns true if the feedback log is currently active (buffer has been created).
65+ /// </summary>
66+ public static bool IsFeedbackLogEnabled
67+ {
68+ get { return s_circularBuffer != null ; }
69+ }
70+
6271 /// <summary>
6372 /// Writes a message to the feedback circular buffer and, if active, to the feedback log file.
6473 /// </summary>
@@ -72,16 +81,39 @@ public static void WriteFeedbackLog(string message)
7281 string timestamp = DateTime . Now . ToString ( "MM/dd/yyyy HH:mm:ss.fff" , CultureInfo . InvariantCulture ) ;
7382 string logLine = string . Format ( CultureInfo . InvariantCulture , "{0}: {1}" , timestamp , message ) ;
7483
75- s_circularBuffer . Write ( logLine ) ;
84+ EnsureFeedbackBuffer ( ) . Write ( logLine ) ;
7685 s_feedbackLogger ? . Write ( logLine ) ;
7786 }
7887
88+ private static FeedbackLogBuffer EnsureFeedbackBuffer ( )
89+ {
90+ if ( s_circularBuffer == null )
91+ {
92+ Interlocked . CompareExchange ( ref s_circularBuffer , new FeedbackLogBuffer ( ) , null ) ;
93+ }
94+
95+ return s_circularBuffer ;
96+ }
97+
98+ /// <summary>
99+ /// Returns true if the feedback buffer has been created and has entries.
100+ /// This is a cheap check to avoid unnecessary work in non-MIEngine scenarios.
101+ /// </summary>
102+ internal static bool HasFeedbackEntries
103+ {
104+ get
105+ {
106+ FeedbackLogBuffer buffer = s_circularBuffer ;
107+ return buffer != null && ! buffer . IsEmpty ;
108+ }
109+ }
110+
79111 /// <summary>
80112 /// Returns log entries added since the last flush, then advances the flush marker.
81113 /// </summary>
82114 internal static IReadOnlyCollection < string > GetNewFeedbackEntries ( )
83115 {
84- return s_circularBuffer . FlushNewEntries ( ) ;
116+ return s_circularBuffer ? . FlushNewEntries ( ) ?? Array . Empty < string > ( ) ;
85117 }
86118
87119 /// <summary>
0 commit comments