@@ -266,6 +266,7 @@ def _add_reader(self, fd, callback, *args):
266266                                  (handle , writer ))
267267            if  reader  is  not None :
268268                reader .cancel ()
269+         return  handle 
269270
270271    def  _remove_reader (self , fd ):
271272        if  self .is_closed ():
@@ -302,6 +303,7 @@ def _add_writer(self, fd, callback, *args):
302303                                  (reader , handle ))
303304            if  writer  is  not None :
304305                writer .cancel ()
306+         return  handle 
305307
306308    def  _remove_writer (self , fd ):
307309        """Remove a writer callback.""" 
@@ -329,7 +331,7 @@ def _remove_writer(self, fd):
329331    def  add_reader (self , fd , callback , * args ):
330332        """Add a reader callback.""" 
331333        self ._ensure_fd_no_transport (fd )
332-         return   self ._add_reader (fd , callback , * args )
334+         self ._add_reader (fd , callback , * args )
333335
334336    def  remove_reader (self , fd ):
335337        """Remove a reader callback.""" 
@@ -339,7 +341,7 @@ def remove_reader(self, fd):
339341    def  add_writer (self , fd , callback , * args ):
340342        """Add a writer callback..""" 
341343        self ._ensure_fd_no_transport (fd )
342-         return   self ._add_writer (fd , callback , * args )
344+         self ._add_writer (fd , callback , * args )
343345
344346    def  remove_writer (self , fd ):
345347        """Remove a writer callback.""" 
@@ -362,13 +364,15 @@ async def sock_recv(self, sock, n):
362364            pass 
363365        fut  =  self .create_future ()
364366        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 )
366369        fut .add_done_callback (
367-             functools .partial (self ._sock_read_done , fd ))
370+             functools .partial (self ._sock_read_done , fd ,  handle = handle ))
368371        return  await  fut 
369372
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 )
372376
373377    def  _sock_recv (self , fut , sock , n ):
374378        # _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):
401405            pass 
402406        fut  =  self .create_future ()
403407        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 )
405410        fut .add_done_callback (
406-             functools .partial (self ._sock_read_done , fd ))
411+             functools .partial (self ._sock_read_done , fd ,  handle = handle ))
407412        return  await  fut 
408413
409414    def  _sock_recv_into (self , fut , sock , buf ):
@@ -446,11 +451,12 @@ async def sock_sendall(self, sock, data):
446451
447452        fut  =  self .create_future ()
448453        fd  =  sock .fileno ()
449-         fut .add_done_callback (
450-             functools .partial (self ._sock_write_done , fd ))
454+         self ._ensure_fd_no_transport (fd )
451455        # 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 ))
454460        return  await  fut 
455461
456462    def  _sock_sendall (self , fut , sock , view , pos ):
@@ -502,18 +508,21 @@ def _sock_connect(self, fut, sock, address):
502508            # connection runs in background. We have to wait until the socket 
503509            # becomes writable to be notified when the connection succeed or 
504510            # fails. 
511+             self ._ensure_fd_no_transport (fd )
512+             handle  =  self ._add_writer (
513+                 fd , self ._sock_connect_cb , fut , sock , address )
505514            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 ))
508516        except  (SystemExit , KeyboardInterrupt ):
509517            raise 
510518        except  BaseException  as  exc :
511519            fut .set_exception (exc )
512520        else :
513521            fut .set_result (None )
514522
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 )
517526
518527    def  _sock_connect_cb (self , fut , sock , address ):
519528        if  fut .done ():
0 commit comments