Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(6)

Side by Side Diff: Lib/asyncio/selector_events.py

Issue 27906: Socket accept exhaustion during high TCP traffic
Patch Set: Created 3 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Lib/asyncio/base_events.py ('k') | Lib/test/test_asyncio/test_base_events.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 """Event loop using a selector and related classes. 1 """Event loop using a selector and related classes.
2 2
3 A selector is a "notify-when-ready" multiplexer. For a subclass which 3 A selector is a "notify-when-ready" multiplexer. For a subclass which
4 also includes support for signal handling, see the unix_events sub-module. 4 also includes support for signal handling, see the unix_events sub-module.
5 """ 5 """
6 6
7 __all__ = ['BaseSelectorEventLoop'] 7 __all__ = ['BaseSelectorEventLoop']
8 8
9 import collections 9 import collections
10 import errno 10 import errno
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 if csock is not None: 144 if csock is not None:
145 try: 145 try:
146 csock.send(b'\0') 146 csock.send(b'\0')
147 except OSError: 147 except OSError:
148 if self._debug: 148 if self._debug:
149 logger.debug("Fail to write a null byte into the " 149 logger.debug("Fail to write a null byte into the "
150 "self-pipe socket", 150 "self-pipe socket",
151 exc_info=True) 151 exc_info=True)
152 152
153 def _start_serving(self, protocol_factory, sock, 153 def _start_serving(self, protocol_factory, sock,
154 sslcontext=None, server=None): 154 sslcontext=None, server=None, backlog=100):
155 self.add_reader(sock.fileno(), self._accept_connection, 155 self.add_reader(sock.fileno(), self._accept_connection,
156 protocol_factory, sock, sslcontext, server) 156 protocol_factory, sock, sslcontext, server, backlog)
157 157
158 def _accept_connection(self, protocol_factory, sock, 158 def _accept_connection(self, protocol_factory, sock,
159 sslcontext=None, server=None): 159 sslcontext=None, server=None, backlog=100):
160 try: 160 for _ in range(backlog):
AntoinePitrou 2016/08/31 10:53:30 Add a comment (with issue #) explaining why the ra
161 conn, addr = sock.accept() 161 try:
162 if self._debug: 162 conn, addr = sock.accept()
163 logger.debug("%r got a new connection from %r: %r", 163 if self._debug:
164 server, addr, conn) 164 logger.debug("%r got a new connection from %r: %r",
165 conn.setblocking(False) 165 server, addr, conn)
166 except (BlockingIOError, InterruptedError, ConnectionAbortedError): 166 conn.setblocking(False)
167 pass # False alarm. 167 except (BlockingIOError, InterruptedError, ConnectionAbortedError):
168 except OSError as exc: 168 # Early exit because the socket accept buffer is empty.
169 # There's nowhere to send the error, so just log it. 169 return None
170 if exc.errno in (errno.EMFILE, errno.ENFILE, 170 except OSError as exc:
171 errno.ENOBUFS, errno.ENOMEM): 171 # There's nowhere to send the error, so just log it.
172 # Some platforms (e.g. Linux keep reporting the FD as 172 if exc.errno in (errno.EMFILE, errno.ENFILE,
173 # ready, so we remove the read handler temporarily. 173 errno.ENOBUFS, errno.ENOMEM):
174 # We'll try again in a while. 174 # Some platforms (e.g. Linux keep reporting the FD as
175 self.call_exception_handler({ 175 # ready, so we remove the read handler temporarily.
176 'message': 'socket.accept() out of system resource', 176 # We'll try again in a while.
177 'exception': exc, 177 self.call_exception_handler({
178 'socket': sock, 178 'message': 'socket.accept() out of system resource',
179 }) 179 'exception': exc,
180 self.remove_reader(sock.fileno()) 180 'socket': sock,
181 self.call_later(constants.ACCEPT_RETRY_DELAY, 181 })
182 self._start_serving, 182 self.remove_reader(sock.fileno())
183 protocol_factory, sock, sslcontext, server) 183 self.call_later(constants.ACCEPT_RETRY_DELAY,
184 self._start_serving,
185 protocol_factory, sock, sslcontext, server,
186 backlog)
187 else:
188 raise # The event loop will catch, log and ignore it.
184 else: 189 else:
185 raise # The event loop will catch, log and ignore it. 190 extra = {'peername': addr}
186 else: 191 accept = self._accept_connection2(protocol_factory, conn, extra,
187 extra = {'peername': addr} 192 sslcontext, server)
188 accept = self._accept_connection2(protocol_factory, conn, extra, 193 self.create_task(accept)
189 sslcontext, server)
190 self.create_task(accept)
191 194
192 @coroutine 195 @coroutine
193 def _accept_connection2(self, protocol_factory, conn, extra, 196 def _accept_connection2(self, protocol_factory, conn, extra,
194 sslcontext=None, server=None): 197 sslcontext=None, server=None):
195 protocol = None 198 protocol = None
196 transport = None 199 transport = None
197 try: 200 try:
198 protocol = protocol_factory() 201 protocol = protocol_factory()
199 waiter = self.create_future() 202 waiter = self.create_future()
200 if sslcontext: 203 if sslcontext:
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 except Exception as exc: 1083 except Exception as exc:
1081 self._fatal_error(exc, 1084 self._fatal_error(exc,
1082 'Fatal write error on datagram transport') 1085 'Fatal write error on datagram transport')
1083 return 1086 return
1084 1087
1085 self._maybe_resume_protocol() # May append to buffer. 1088 self._maybe_resume_protocol() # May append to buffer.
1086 if not self._buffer: 1089 if not self._buffer:
1087 self._loop.remove_writer(self._sock_fd) 1090 self._loop.remove_writer(self._sock_fd)
1088 if self._closing: 1091 if self._closing:
1089 self._call_connection_lost(None) 1092 self._call_connection_lost(None)
OLDNEW
« no previous file with comments | « Lib/asyncio/base_events.py ('k') | Lib/test/test_asyncio/test_base_events.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+