@@ -266,6 +266,7 @@ def _add_reader(self, fd, callback, *args):
266
266
(handle , writer ))
267
267
if reader is not None :
268
268
reader .cancel ()
269
+ return handle
269
270
270
271
def _remove_reader (self , fd ):
271
272
if self .is_closed ():
@@ -302,6 +303,7 @@ def _add_writer(self, fd, callback, *args):
302
303
(reader , handle ))
303
304
if writer is not None :
304
305
writer .cancel ()
306
+ return handle
305
307
306
308
def _remove_writer (self , fd ):
307
309
"""Remove a writer callback."""
@@ -329,7 +331,7 @@ def _remove_writer(self, fd):
329
331
def add_reader (self , fd , callback , * args ):
330
332
"""Add a reader callback."""
331
333
self ._ensure_fd_no_transport (fd )
332
- return self ._add_reader (fd , callback , * args )
334
+ self ._add_reader (fd , callback , * args )
333
335
334
336
def remove_reader (self , fd ):
335
337
"""Remove a reader callback."""
@@ -339,7 +341,7 @@ def remove_reader(self, fd):
339
341
def add_writer (self , fd , callback , * args ):
340
342
"""Add a writer callback.."""
341
343
self ._ensure_fd_no_transport (fd )
342
- return self ._add_writer (fd , callback , * args )
344
+ self ._add_writer (fd , callback , * args )
343
345
344
346
def remove_writer (self , fd ):
345
347
"""Remove a writer callback."""
@@ -362,13 +364,15 @@ async def sock_recv(self, sock, n):
362
364
pass
363
365
fut = self .create_future ()
364
366
fd = sock .fileno ()
365
- self .add_reader (fd , self ._sock_recv , fut , sock , n )
367
+ self ._ensure_fd_no_transport (fd )
368
+ handle = self ._add_reader (fd , self ._sock_recv , fut , sock , n )
366
369
fut .add_done_callback (
367
- functools .partial (self ._sock_read_done , fd ))
370
+ functools .partial (self ._sock_read_done , fd , handle = handle ))
368
371
return await fut
369
372
370
- def _sock_read_done (self , fd , fut ):
371
- self .remove_reader (fd )
373
+ def _sock_read_done (self , fd , fut , handle = None ):
374
+ if handle is None or not handle .cancelled ():
375
+ self .remove_reader (fd )
372
376
373
377
def _sock_recv (self , fut , sock , n ):
374
378
# _sock_recv() can add itself as an I/O callback if the operation can't
@@ -401,9 +405,10 @@ async def sock_recv_into(self, sock, buf):
401
405
pass
402
406
fut = self .create_future ()
403
407
fd = sock .fileno ()
404
- self .add_reader (fd , self ._sock_recv_into , fut , sock , buf )
408
+ self ._ensure_fd_no_transport (fd )
409
+ handle = self ._add_reader (fd , self ._sock_recv_into , fut , sock , buf )
405
410
fut .add_done_callback (
406
- functools .partial (self ._sock_read_done , fd ))
411
+ functools .partial (self ._sock_read_done , fd , handle = handle ))
407
412
return await fut
408
413
409
414
def _sock_recv_into (self , fut , sock , buf ):
@@ -446,11 +451,12 @@ async def sock_sendall(self, sock, data):
446
451
447
452
fut = self .create_future ()
448
453
fd = sock .fileno ()
449
- fut .add_done_callback (
450
- functools .partial (self ._sock_write_done , fd ))
454
+ self ._ensure_fd_no_transport (fd )
451
455
# use a trick with a list in closure to store a mutable state
452
- self .add_writer (fd , self ._sock_sendall , fut , sock ,
453
- memoryview (data ), [n ])
456
+ handle = self ._add_writer (fd , self ._sock_sendall , fut , sock ,
457
+ memoryview (data ), [n ])
458
+ fut .add_done_callback (
459
+ functools .partial (self ._sock_write_done , fd , handle = handle ))
454
460
return await fut
455
461
456
462
def _sock_sendall (self , fut , sock , view , pos ):
@@ -502,18 +508,21 @@ def _sock_connect(self, fut, sock, address):
502
508
# connection runs in background. We have to wait until the socket
503
509
# becomes writable to be notified when the connection succeed or
504
510
# fails.
511
+ self ._ensure_fd_no_transport (fd )
512
+ handle = self ._add_writer (
513
+ fd , self ._sock_connect_cb , fut , sock , address )
505
514
fut .add_done_callback (
506
- functools .partial (self ._sock_write_done , fd ))
507
- self .add_writer (fd , self ._sock_connect_cb , fut , sock , address )
515
+ functools .partial (self ._sock_write_done , fd , handle = handle ))
508
516
except (SystemExit , KeyboardInterrupt ):
509
517
raise
510
518
except BaseException as exc :
511
519
fut .set_exception (exc )
512
520
else :
513
521
fut .set_result (None )
514
522
515
- def _sock_write_done (self , fd , fut ):
516
- self .remove_writer (fd )
523
+ def _sock_write_done (self , fd , fut , handle = None ):
524
+ if handle is None or not handle .cancelled ():
525
+ self .remove_writer (fd )
517
526
518
527
def _sock_connect_cb (self , fut , sock , address ):
519
528
if fut .done ():
0 commit comments