1010using System . Threading ;
1111using Microsoft . Build . BackEnd . Components . RequestBuilder ;
1212using Microsoft . Build . Evaluation ;
13+ using Microsoft . Build . Experimental . BuildCheck ;
1314using Microsoft . Build . Experimental . BuildCheck . Infrastructure ;
1415using Microsoft . Build . Framework ;
1516using Microsoft . Build . Shared ;
1617using InternalLoggerException = Microsoft . Build . Exceptions . InternalLoggerException ;
1718using LoggerDescription = Microsoft . Build . Logging . LoggerDescription ;
18- using Microsoft . Build . Experimental . BuildCheck ;
1919
2020#nullable disable
2121
@@ -62,7 +62,7 @@ internal enum LoggingServiceState
6262 ShuttingDown ,
6363
6464 /// <summary>
65- /// The logging service completly shutdown
65+ /// The logging service completely shutdown.
6666 /// </summary>
6767 Shutdown
6868 }
@@ -253,12 +253,14 @@ internal partial class LoggingService : ILoggingService, INodePacketHandler
253253 /// Event set when message is consumed from queue.
254254 /// </summary>
255255 private AutoResetEvent _dequeueEvent ;
256+
256257 /// <summary>
257- /// Event set when queue become empty.
258+ /// Event set when queue become empty.
258259 /// </summary>
259260 private ManualResetEvent _emptyQueueEvent ;
261+
260262 /// <summary>
261- /// Even set when message is added into queue.
263+ /// Event set when message is added into queue.
262264 /// </summary>
263265 private AutoResetEvent _enqueueEvent ;
264266
@@ -1408,34 +1410,47 @@ private void StartLoggingEventProcessing()
14081410 void LoggingEventProc ( )
14091411 {
14101412 var completeAdding = _loggingEventProcessingCancellation . Token ;
1411- WaitHandle [ ] waitHandlesForNextEvent = { completeAdding . WaitHandle , _enqueueEvent } ;
1413+ WaitHandle [ ] waitHandlesForNextEvent = [ completeAdding . WaitHandle , _enqueueEvent ] ;
14121414
1413- do
1415+ try
14141416 {
1415- if ( _eventQueue . TryDequeue ( out object ev ) )
1416- {
1417- LoggingEventProcessor ( ev ) ;
1418- _dequeueEvent . Set ( ) ;
1419- }
1420- else
1421- {
1422- _emptyQueueEvent . Set ( ) ;
1417+ // Store field references locally to prevent race with cleanup
1418+ var eventQueue = _eventQueue ;
1419+ var dequeueEvent = _dequeueEvent ;
1420+ var emptyQueueEvent = _emptyQueueEvent ;
1421+ var enqueueEvent = _enqueueEvent ;
14231422
1424- // Wait for next event, or finish.
1425- if ( ! completeAdding . IsCancellationRequested && _eventQueue . IsEmpty )
1423+ do
1424+ {
1425+ if ( eventQueue . TryDequeue ( out object ev ) )
14261426 {
1427- WaitHandle . WaitAny ( waitHandlesForNextEvent ) ;
1427+ LoggingEventProcessor ( ev ) ;
1428+ dequeueEvent ? . Set ( ) ;
14281429 }
1430+ else
1431+ {
1432+ emptyQueueEvent ? . Set ( ) ;
14291433
1430- _emptyQueueEvent . Reset ( ) ;
1431- }
1432- } while ( ! _eventQueue . IsEmpty || ! completeAdding . IsCancellationRequested ) ;
1434+ // Wait for next event, or finish.
1435+ if ( ! completeAdding . IsCancellationRequested && eventQueue . IsEmpty )
1436+ {
1437+ WaitHandle . WaitAny ( waitHandlesForNextEvent ) ;
1438+ }
14331439
1434- _emptyQueueEvent . Set ( ) ;
1440+ emptyQueueEvent . Reset ( ) ;
1441+ }
1442+ } while ( ! eventQueue . IsEmpty || ! completeAdding . IsCancellationRequested ) ;
1443+
1444+ emptyQueueEvent . Set ( ) ;
1445+ }
1446+ catch ( ObjectDisposedException )
1447+ {
1448+ // Events/queue were disposed during shutdown, exit processing
1449+ return ;
1450+ }
14351451 }
14361452 }
14371453
1438-
14391454 /// <summary>
14401455 /// Clean resources used for logging event processing queue.
14411456 /// </summary>
@@ -1448,9 +1463,11 @@ private void CleanLoggingEventProcessing()
14481463 _loggingEventProcessingCancellation ? . Dispose ( ) ;
14491464
14501465 _eventQueue = null ;
1466+
14511467 _dequeueEvent = null ;
14521468 _enqueueEvent = null ;
14531469 _emptyQueueEvent = null ;
1470+
14541471 _loggingEventProcessingCancellation = null ;
14551472 _loggingEventProcessingThread = null ;
14561473 }
0 commit comments