@@ -934,20 +934,40 @@ private void StartBacklogProcessor()
934934 {
935935 if ( Interlocked . CompareExchange ( ref _backlogProcessorIsRunning , 1 , 0 ) == 0 )
936936 {
937- _backlogStatus = BacklogStatus . Activating ;
938-
939- // Start the backlog processor; this is a bit unorthodox, as you would *expect* this to just
940- // be Task.Run; that would work fine when healthy, but when we're falling on our face, it is
941- // easy to get into a thread-pool-starvation "spiral of death" if we rely on the thread-pool
942- // to unblock the thread-pool when there could be sync-over-async callers. Note that in reality,
943- // the initial "enough" of the back-log processor is typically sync, which means that the thread
944- // we start is actually useful, despite thinking "but that will just go async and back to the pool"
945- var thread = new Thread ( s => ( ( PhysicalBridge ) s ! ) . ProcessBacklog ( ) )
937+ var successfullyStarted = false ;
938+ try
939+ {
940+ _backlogStatus = BacklogStatus . Activating ;
941+
942+ // Start the backlog processor; this is a bit unorthodox, as you would *expect* this to just
943+ // be Task.Run; that would work fine when healthy, but when we're falling on our face, it is
944+ // easy to get into a thread-pool-starvation "spiral of death" if we rely on the thread-pool
945+ // to unblock the thread-pool when there could be sync-over-async callers. Note that in reality,
946+ // the initial "enough" of the back-log processor is typically sync, which means that the thread
947+ // we start is actually useful, despite thinking "but that will just go async and back to the pool"
948+ var thread = new Thread ( s => ( ( PhysicalBridge ) s ! ) . ProcessBacklog ( ) )
949+ {
950+ IsBackground = true , // don't keep process alive (also: act like the thread-pool used to)
951+ Name = "StackExchange.Redis Backlog" , // help anyone looking at thread-dumps
952+ } ;
953+
954+ thread . Start ( this ) ;
955+ successfullyStarted = true ;
956+ }
957+ catch ( Exception ex )
946958 {
947- IsBackground = true , // don't keep process alive (also: act like the thread-pool used to)
948- Name = "StackExchange.Redis Backlog" , // help anyone looking at thread-dumps
949- } ;
950- thread . Start ( this ) ;
959+ OnInternalError ( ex ) ;
960+ Trace ( "StartBacklogProcessor failed to start backlog processor thread: " + ex . Message ) ;
961+ }
962+ finally
963+ {
964+ // If thread failed to start - reset flag to ensure next call doesn't erroneously think backlog process is running
965+ if ( ! successfullyStarted )
966+ {
967+ _backlogStatus = BacklogStatus . Inactive ;
968+ Interlocked . Exchange ( ref _backlogProcessorIsRunning , 0 ) ;
969+ }
970+ }
951971 }
952972 else
953973 {
0 commit comments