@@ -155,12 +155,20 @@ private void StartAccept ( int poolIndex ) {
155155 return ;
156156 }
157157 catch ( ObjectDisposedException ) {
158+ if ( _isListening && Volatile . Read ( ref _listenerRestarting ) == 0 )
159+ TriggerListenerRebuild ( ) ;
160+
158161 return ;
159162 }
160- catch ( SocketException ) {
163+ catch ( SocketException ex ) {
161164 if ( Volatile . Read ( ref _listenerRestarting ) == 1 )
162165 return ;
163166
167+ if ( IsListenerFatalError ( ex . SocketErrorCode ) ) {
168+ TriggerListenerRebuild ( ) ;
169+ return ;
170+ }
171+
164172 QueueStartAccept ( poolIndex , ListenerAcceptRetryDelayMilliseconds ) ;
165173 return ;
166174 }
@@ -222,27 +230,39 @@ or SocketError.OperationAborted
222230 or SocketError . Interrupted ;
223231
224232 private void TriggerListenerRebuild ( ) {
233+ if ( ! _isListening || _disposedValue )
234+ return ;
235+
225236 if ( Interlocked . CompareExchange ( ref _listenerRestarting , 1 , 0 ) != 0 )
226237 return ;
227238
228239 _ = RebuildListenerAsync ( ) ;
229240 }
230241
231242 private async Task RebuildListenerAsync ( ) {
232- try { _listener . Close ( ) ; } catch { }
233- try { _listener . Dispose ( ) ; } catch { }
243+ Socket oldListener = _listener ;
244+
245+ try { oldListener . Close ( ) ; } catch { }
246+ try { oldListener . Dispose ( ) ; } catch { }
234247
235248 while ( _isListening && ! _disposedValue ) {
236249 await Task . Delay ( ListenerAcceptRetryDelayMilliseconds ) . ConfigureAwait ( false ) ;
237250
251+ Socket ? newListener = null ;
238252 try {
239- Socket newListener = CreateListenerSocket ( ) ;
253+ newListener = CreateListenerSocket ( ) ;
240254 newListener . Bind ( _endpoint ) ;
241255 newListener . Listen ( backlog : 4096 ) ;
256+
242257 _listener = newListener ;
243258 break ;
244259 }
245260 catch ( SocketException ) {
261+ try { newListener ? . Dispose ( ) ; } catch { }
262+ }
263+ catch ( ObjectDisposedException ) {
264+ try { newListener ? . Dispose ( ) ; } catch { }
265+ break ;
246266 }
247267 }
248268
0 commit comments