@@ -1090,6 +1090,9 @@ cdef class SSLTransport_Socket(SSLTransportBase):
10901090 # Are we registered for _write_ready in the event loop?
10911091 bint _write_ready_registered
10921092
1093+ # Has any sys write failed with EAGAIN during current _write_ready run
1094+ bint _write_had_eagain
1095+
10931096 def __init__ (self , loop , sock , app_protocol , sslcontext ,
10941097 *,
10951098 waiter = None ,
@@ -1125,6 +1128,9 @@ cdef class SSLTransport_Socket(SSLTransportBase):
11251128
11261129 self ._write_watermarks = WriteWatermarks(loop)
11271130
1131+ self ._write_ready_registered = False
1132+ self ._write_had_eagain = False
1133+
11281134 self ._loop.add_reader(self ._sock_fd_obj, self ._read_ready)
11291135 self ._start_handshake()
11301136
@@ -1189,7 +1195,7 @@ cdef class SSLTransport_Socket(SSLTransportBase):
11891195 if self ._ssl_object.outgoing == NULL :
11901196 return True
11911197
1192- if self ._write_ready_registered :
1198+ if self ._write_had_eagain :
11931199 return False
11941200
11951201 cdef:
@@ -1232,12 +1238,19 @@ cdef class SSLTransport_Socket(SSLTransportBase):
12321238 return not self ._write_ready_registered
12331239
12341240 cdef inline _ensure_writer(self ):
1241+ if unlikely(self ._is_debug):
1242+ _logger.debug(" %r : _ensure_writer called" , self )
1243+
1244+ self ._write_had_eagain = True
12351245 if self ._connection_lost_scheduled or self ._write_ready_registered:
12361246 return
12371247 self ._write_ready_registered = True
12381248 self ._loop.add_writer(self ._sock_fd_obj, self ._write_ready)
12391249
12401250 cdef inline _drop_writer(self ):
1251+ if unlikely(self ._is_debug):
1252+ _logger.debug(" %r : _drop_writer called" , self )
1253+
12411254 if self ._sock is None or not self ._write_ready_registered:
12421255 return
12431256 self ._write_ready_registered = False
@@ -1250,8 +1263,13 @@ cdef class SSLTransport_Socket(SSLTransportBase):
12501263 if self ._connection_lost_scheduled:
12511264 return
12521265
1266+ # Reset _write_had_eagain
1267+ # If any system write fails with EAGAIN it suppose to call _ensure_writer
1268+ # _ensure_writer will set _write_had_eagain = True
1269+ # At the end of _write_ready we deregister if nobody has set _write_had_eagain
1270+ self ._write_had_eagain = False
1271+
12531272 try :
1254- self ._drop_writer()
12551273 self ._flush_outgoing_bio()
12561274
12571275 if self ._state == SSLProtocolState.DO_HANDSHAKE:
@@ -1265,7 +1283,11 @@ cdef class SSLTransport_Socket(SSLTransportBase):
12651283 self ._do_flush()
12661284 elif self ._state == SSLProtocolState.SHUTDOWN:
12671285 self ._do_shutdown()
1286+
1287+ if not self ._write_had_eagain:
1288+ self ._drop_writer()
12681289 except BaseException as exc:
1290+ # _fatal_error will always _drop_writer()
12691291 self ._fatal_error(exc, " Error occurred during write" )
12701292
12711293 cdef _check_sendfile_supported(self ):
0 commit comments