mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	bpo-41317: Remove reader on cancellation in asyncio.loop.sock_accept() (GH-21595)
(cherry picked from commit 0dd98c2d00)
Co-authored-by: Alex Grönholm <alex.gronholm@nextday.fi>
			
			
This commit is contained in:
		
							parent
							
								
									e8dda907fb
								
							
						
					
					
						commit
						4ff8e5ba4f
					
				
					 3 changed files with 27 additions and 7 deletions
				
			
		|  | @ -555,20 +555,19 @@ async def sock_accept(self, sock): | |||
|         if self._debug and sock.gettimeout() != 0: | ||||
|             raise ValueError("the socket must be non-blocking") | ||||
|         fut = self.create_future() | ||||
|         self._sock_accept(fut, False, sock) | ||||
|         self._sock_accept(fut, sock) | ||||
|         return await fut | ||||
| 
 | ||||
|     def _sock_accept(self, fut, registered, sock): | ||||
|     def _sock_accept(self, fut, sock): | ||||
|         fd = sock.fileno() | ||||
|         if registered: | ||||
|             self.remove_reader(fd) | ||||
|         if fut.done(): | ||||
|             return | ||||
|         try: | ||||
|             conn, address = sock.accept() | ||||
|             conn.setblocking(False) | ||||
|         except (BlockingIOError, InterruptedError): | ||||
|             self.add_reader(fd, self._sock_accept, fut, True, sock) | ||||
|             self._ensure_fd_no_transport(fd) | ||||
|             handle = self._add_reader(fd, self._sock_accept, fut, sock) | ||||
|             fut.add_done_callback( | ||||
|                 functools.partial(self._sock_read_done, fd, handle=handle)) | ||||
|         except (SystemExit, KeyboardInterrupt): | ||||
|             raise | ||||
|         except BaseException as exc: | ||||
|  |  | |||
|  | @ -415,6 +415,25 @@ def test_sock_accept(self): | |||
|         conn.close() | ||||
|         listener.close() | ||||
| 
 | ||||
|     def test_cancel_sock_accept(self): | ||||
|         listener = socket.socket() | ||||
|         listener.setblocking(False) | ||||
|         listener.bind(('127.0.0.1', 0)) | ||||
|         listener.listen(1) | ||||
|         sockaddr = listener.getsockname() | ||||
|         f = asyncio.wait_for(self.loop.sock_accept(listener), 0.1) | ||||
|         with self.assertRaises(asyncio.TimeoutError): | ||||
|             self.loop.run_until_complete(f) | ||||
| 
 | ||||
|         listener.close() | ||||
|         client = socket.socket() | ||||
|         client.setblocking(False) | ||||
|         f = self.loop.sock_connect(client, sockaddr) | ||||
|         with self.assertRaises(ConnectionRefusedError): | ||||
|             self.loop.run_until_complete(f) | ||||
| 
 | ||||
|         client.close() | ||||
| 
 | ||||
|     def test_create_connection_sock(self): | ||||
|         with test_utils.run_test_server() as httpd: | ||||
|             sock = None | ||||
|  |  | |||
|  | @ -0,0 +1,2 @@ | |||
| Use add_done_callback() in asyncio.loop.sock_accept() to unsubscribe reader | ||||
| early on cancellation. | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)