@@ -344,7 +344,7 @@ def __init__(self, loop, sock, protocol, extra, server=None):
344344 self ._protocol = protocol
345345 self ._server = server
346346 self ._buffer = collections .deque ()
347- self ._conn_lost = 0
347+ self ._conn_lost = 0 # Set when call to connection_lost scheduled.
348348 self ._closing = False # Set when close() called.
349349 if server is not None :
350350 server .attach (self )
@@ -356,27 +356,27 @@ def close(self):
356356 if self ._closing :
357357 return
358358 self ._closing = True
359- self ._conn_lost += 1
360359 self ._loop .remove_reader (self ._sock_fd )
361360 if not self ._buffer :
361+ self ._conn_lost += 1
362362 self ._loop .call_soon (self ._call_connection_lost , None )
363363
364364 def _fatal_error (self , exc ):
365- # should be called from exception handler only
366- logger .exception ('Fatal error for %s' , self )
365+ # Should be called from exception handler only.
366+ if not isinstance (exc , (BrokenPipeError , ConnectionResetError )):
367+ logger .exception ('Fatal error for %s' , self )
367368 self ._force_close (exc )
368369
369370 def _force_close (self , exc ):
371+ if self ._conn_lost :
372+ return
370373 if self ._buffer :
371374 self ._buffer .clear ()
372375 self ._loop .remove_writer (self ._sock_fd )
373-
374- if self ._closing :
375- return
376-
377- self ._closing = True
376+ if not self ._closing :
377+ self ._closing = True
378+ self ._loop .remove_reader (self ._sock_fd )
378379 self ._conn_lost += 1
379- self ._loop .remove_reader (self ._sock_fd )
380380 self ._loop .call_soon (self ._call_connection_lost , exc )
381381
382382 def _call_connection_lost (self , exc ):
@@ -424,8 +424,6 @@ def _read_ready(self):
424424 data = self ._sock .recv (self .max_size )
425425 except (BlockingIOError , InterruptedError ):
426426 pass
427- except ConnectionResetError as exc :
428- self ._force_close (exc )
429427 except Exception as exc :
430428 self ._fatal_error (exc )
431429 else :
@@ -453,17 +451,15 @@ def write(self, data):
453451 try :
454452 n = self ._sock .send (data )
455453 except (BlockingIOError , InterruptedError ):
456- n = 0
457- except (BrokenPipeError , ConnectionResetError ) as exc :
458- self ._force_close (exc )
459- return
460- except OSError as exc :
454+ pass
455+ except Exception as exc :
461456 self ._fatal_error (exc )
462457 return
463458 else :
464459 data = data [n :]
465460 if not data :
466461 return
462+
467463 # Start async I/O.
468464 self ._loop .add_writer (self ._sock_fd , self ._write_ready )
469465
@@ -478,9 +474,6 @@ def _write_ready(self):
478474 n = self ._sock .send (data )
479475 except (BlockingIOError , InterruptedError ):
480476 self ._buffer .append (data )
481- except (BrokenPipeError , ConnectionResetError ) as exc :
482- self ._loop .remove_writer (self ._sock_fd )
483- self ._force_close (exc )
484477 except Exception as exc :
485478 self ._loop .remove_writer (self ._sock_fd )
486479 self ._fatal_error (exc )
@@ -493,7 +486,6 @@ def _write_ready(self):
493486 elif self ._eof :
494487 self ._sock .shutdown (socket .SHUT_WR )
495488 return
496-
497489 self ._buffer .append (data ) # Try again later.
498490
499491 def write_eof (self ):
@@ -622,8 +614,6 @@ def _on_ready(self):
622614 except (BlockingIOError , InterruptedError ,
623615 ssl .SSLWantReadError , ssl .SSLWantWriteError ):
624616 pass
625- except ConnectionResetError as exc :
626- self ._force_close (exc )
627617 except Exception as exc :
628618 self ._fatal_error (exc )
629619 else :
@@ -644,10 +634,6 @@ def _on_ready(self):
644634 except (BlockingIOError , InterruptedError ,
645635 ssl .SSLWantReadError , ssl .SSLWantWriteError ):
646636 n = 0
647- except (BrokenPipeError , ConnectionResetError ) as exc :
648- self ._loop .remove_writer (self ._sock_fd )
649- self ._force_close (exc )
650- return
651637 except Exception as exc :
652638 self ._loop .remove_writer (self ._sock_fd )
653639 self ._fatal_error (exc )
@@ -726,12 +712,12 @@ def sendto(self, data, addr=None):
726712 else :
727713 self ._sock .sendto (data , addr )
728714 return
715+ except (BlockingIOError , InterruptedError ):
716+ self ._loop .add_writer (self ._sock_fd , self ._sendto_ready )
729717 except ConnectionRefusedError as exc :
730718 if self ._address :
731719 self ._fatal_error (exc )
732720 return
733- except (BlockingIOError , InterruptedError ):
734- self ._loop .add_writer (self ._sock_fd , self ._sendto_ready )
735721 except Exception as exc :
736722 self ._fatal_error (exc )
737723 return
@@ -746,13 +732,13 @@ def _sendto_ready(self):
746732 self ._sock .send (data )
747733 else :
748734 self ._sock .sendto (data , addr )
735+ except (BlockingIOError , InterruptedError ):
736+ self ._buffer .appendleft ((data , addr )) # Try again later.
737+ break
749738 except ConnectionRefusedError as exc :
750739 if self ._address :
751740 self ._fatal_error (exc )
752741 return
753- except (BlockingIOError , InterruptedError ):
754- self ._buffer .appendleft ((data , addr )) # Try again later.
755- break
756742 except Exception as exc :
757743 self ._fatal_error (exc )
758744 return
@@ -765,5 +751,4 @@ def _sendto_ready(self):
765751 def _force_close (self , exc ):
766752 if self ._address and isinstance (exc , ConnectionRefusedError ):
767753 self ._protocol .connection_refused (exc )
768-
769754 super ()._force_close (exc )
0 commit comments