blob: 0ad06564187285d6eee18758ae10e6083676a4a3 [file] [log] [blame]
Guido van Rossum27b7c7e2013-10-17 13:40:50 -07001"""Event loop using a proactor and related classes.
2
3A proactor is a "notify-on-completion" multiplexer. Currently a
4proactor is only implemented on Windows with IOCP.
5"""
6
Victor Stinner8dffc452014-01-25 15:32:06 +01007__all__ = ['BaseProactorEventLoop']
8
Guido van Rossum27b7c7e2013-10-17 13:40:50 -07009import socket
10
11from . import base_events
12from . import constants
13from . import futures
14from . import transports
Guido van Rossumfc29e0f2013-10-17 15:39:45 -070015from .log import logger
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070016
17
Yury Selivanov3cb99142014-02-18 18:41:13 -050018class _ProactorBasePipeTransport(transports._FlowControlMixin,
19 transports.BaseTransport):
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070020 """Base class for pipe and socket transports."""
21
22 def __init__(self, loop, sock, protocol, waiter=None,
23 extra=None, server=None):
24 super().__init__(extra)
25 self._set_extra(sock)
26 self._loop = loop
27 self._sock = sock
28 self._protocol = protocol
29 self._server = server
Guido van Rossumebb8e582013-12-04 12:12:07 -080030 self._buffer = None # None or bytearray.
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070031 self._read_fut = None
32 self._write_fut = None
Victor Stinner915bcb02014-02-01 22:49:59 +010033 self._pending_write = 0
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070034 self._conn_lost = 0
35 self._closing = False # Set when close() called.
36 self._eof_written = False
37 if self._server is not None:
Victor Stinnerb28dbac2014-07-11 22:52:21 +020038 self._server._attach()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070039 self._loop.call_soon(self._protocol.connection_made, self)
40 if waiter is not None:
Victor Stinnerbfff45d2014-07-08 23:57:31 +020041 # wait until protocol.connection_made() has been called
Victor Stinner799a60c2014-07-07 18:08:22 +020042 self._loop.call_soon(waiter._set_result_unless_cancelled, None)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070043
Victor Stinnere912e652014-07-12 03:11:53 +020044 def __repr__(self):
45 info = [self.__class__.__name__, 'fd=%s' % self._sock.fileno()]
46 if self._read_fut is not None:
Victor Stinner18a28dc2014-07-25 13:05:20 +020047 info.append('read=%s' % self._read_fut)
Victor Stinnere912e652014-07-12 03:11:53 +020048 if self._write_fut is not None:
Victor Stinner18a28dc2014-07-25 13:05:20 +020049 info.append("write=%r" % self._write_fut)
Victor Stinnere912e652014-07-12 03:11:53 +020050 if self._buffer:
51 bufsize = len(self._buffer)
52 info.append('write_bufsize=%s' % bufsize)
53 if self._eof_written:
54 info.append('EOF written')
55 return '<%s>' % ' '.join(info)
56
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070057 def _set_extra(self, sock):
58 self._extra['pipe'] = sock
59
60 def close(self):
61 if self._closing:
62 return
63 self._closing = True
64 self._conn_lost += 1
65 if not self._buffer and self._write_fut is None:
66 self._loop.call_soon(self._call_connection_lost, None)
67 if self._read_fut is not None:
68 self._read_fut.cancel()
69
Victor Stinner0ee29c22014-02-19 01:40:41 +010070 def _fatal_error(self, exc, message='Fatal error on pipe transport'):
Victor Stinnere912e652014-07-12 03:11:53 +020071 if isinstance(exc, (BrokenPipeError, ConnectionResetError)):
72 if self._loop.get_debug():
73 logger.debug("%r: %s", self, message, exc_info=True)
74 else:
Yury Selivanov569efa22014-02-18 18:02:19 -050075 self._loop.call_exception_handler({
Victor Stinner0ee29c22014-02-19 01:40:41 +010076 'message': message,
Yury Selivanov569efa22014-02-18 18:02:19 -050077 'exception': exc,
78 'transport': self,
79 'protocol': self._protocol,
80 })
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070081 self._force_close(exc)
82
83 def _force_close(self, exc):
84 if self._closing:
85 return
86 self._closing = True
87 self._conn_lost += 1
88 if self._write_fut:
89 self._write_fut.cancel()
90 if self._read_fut:
91 self._read_fut.cancel()
92 self._write_fut = self._read_fut = None
Victor Stinner915bcb02014-02-01 22:49:59 +010093 self._pending_write = 0
Guido van Rossumebb8e582013-12-04 12:12:07 -080094 self._buffer = None
Guido van Rossum27b7c7e2013-10-17 13:40:50 -070095 self._loop.call_soon(self._call_connection_lost, exc)
96
97 def _call_connection_lost(self, exc):
98 try:
99 self._protocol.connection_lost(exc)
100 finally:
101 # XXX If there is a pending overlapped read on the other
102 # end then it may fail with ERROR_NETNAME_DELETED if we
103 # just close our end. First calling shutdown() seems to
104 # cure it, but maybe using DisconnectEx() would be better.
105 if hasattr(self._sock, 'shutdown'):
106 self._sock.shutdown(socket.SHUT_RDWR)
107 self._sock.close()
108 server = self._server
109 if server is not None:
Victor Stinnerb28dbac2014-07-11 22:52:21 +0200110 server._detach()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700111 self._server = None
112
Guido van Rossumebb8e582013-12-04 12:12:07 -0800113 def get_write_buffer_size(self):
Victor Stinner915bcb02014-02-01 22:49:59 +0100114 size = self._pending_write
115 if self._buffer is not None:
116 size += len(self._buffer)
117 return size
Guido van Rossumebb8e582013-12-04 12:12:07 -0800118
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700119
120class _ProactorReadPipeTransport(_ProactorBasePipeTransport,
121 transports.ReadTransport):
122 """Transport for read pipes."""
123
124 def __init__(self, loop, sock, protocol, waiter=None,
125 extra=None, server=None):
126 super().__init__(loop, sock, protocol, waiter, extra, server)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700127 self._paused = False
128 self._loop.call_soon(self._loop_reading)
129
Guido van Rossum57497ad2013-10-18 07:58:20 -0700130 def pause_reading(self):
Guido van Rossumebb8e582013-12-04 12:12:07 -0800131 if self._closing:
132 raise RuntimeError('Cannot pause_reading() when closing')
133 if self._paused:
134 raise RuntimeError('Already paused')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700135 self._paused = True
Victor Stinnere912e652014-07-12 03:11:53 +0200136 if self._loop.get_debug():
137 logger.debug("%r pauses reading", self)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700138
Guido van Rossum57497ad2013-10-18 07:58:20 -0700139 def resume_reading(self):
Guido van Rossumebb8e582013-12-04 12:12:07 -0800140 if not self._paused:
141 raise RuntimeError('Not paused')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700142 self._paused = False
143 if self._closing:
144 return
145 self._loop.call_soon(self._loop_reading, self._read_fut)
Victor Stinnere912e652014-07-12 03:11:53 +0200146 if self._loop.get_debug():
147 logger.debug("%r resumes reading", self)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700148
149 def _loop_reading(self, fut=None):
150 if self._paused:
151 return
152 data = None
153
154 try:
155 if fut is not None:
156 assert self._read_fut is fut or (self._read_fut is None and
157 self._closing)
158 self._read_fut = None
159 data = fut.result() # deliver data later in "finally" clause
160
161 if self._closing:
162 # since close() has been called we ignore any read data
163 data = None
164 return
165
166 if data == b'':
167 # we got end-of-file so no need to reschedule a new read
168 return
169
170 # reschedule a new read
171 self._read_fut = self._loop._proactor.recv(self._sock, 4096)
172 except ConnectionAbortedError as exc:
173 if not self._closing:
Victor Stinner0ee29c22014-02-19 01:40:41 +0100174 self._fatal_error(exc, 'Fatal read error on pipe transport')
Victor Stinnerb2614752014-08-25 23:20:52 +0200175 elif self._loop.get_debug():
176 logger.debug("Read error on pipe transport while closing",
177 exc_info=True)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700178 except ConnectionResetError as exc:
179 self._force_close(exc)
180 except OSError as exc:
Victor Stinner0ee29c22014-02-19 01:40:41 +0100181 self._fatal_error(exc, 'Fatal read error on pipe transport')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700182 except futures.CancelledError:
183 if not self._closing:
184 raise
185 else:
186 self._read_fut.add_done_callback(self._loop_reading)
187 finally:
188 if data:
189 self._protocol.data_received(data)
190 elif data is not None:
Victor Stinnere912e652014-07-12 03:11:53 +0200191 if self._loop.get_debug():
192 logger.debug("%r received EOF", self)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700193 keep_open = self._protocol.eof_received()
194 if not keep_open:
195 self.close()
196
197
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100198class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport,
Victor Stinner915bcb02014-02-01 22:49:59 +0100199 transports.WriteTransport):
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700200 """Transport for write pipes."""
201
202 def write(self, data):
Guido van Rossumebb8e582013-12-04 12:12:07 -0800203 if not isinstance(data, (bytes, bytearray, memoryview)):
204 raise TypeError('data argument must be byte-ish (%r)',
205 type(data))
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700206 if self._eof_written:
Guido van Rossumebb8e582013-12-04 12:12:07 -0800207 raise RuntimeError('write_eof() already called')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700208
209 if not data:
210 return
211
212 if self._conn_lost:
213 if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES:
Guido van Rossumfc29e0f2013-10-17 15:39:45 -0700214 logger.warning('socket.send() raised exception.')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700215 self._conn_lost += 1
216 return
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700217
Guido van Rossumebb8e582013-12-04 12:12:07 -0800218 # Observable states:
219 # 1. IDLE: _write_fut and _buffer both None
220 # 2. WRITING: _write_fut set; _buffer None
221 # 3. BACKED UP: _write_fut set; _buffer a bytearray
222 # We always copy the data, so the caller can't modify it
223 # while we're still waiting for the I/O to happen.
224 if self._write_fut is None: # IDLE -> WRITING
225 assert self._buffer is None
226 # Pass a copy, except if it's already immutable.
227 self._loop_writing(data=bytes(data))
228 # XXX Should we pause the protocol at this point
229 # if len(data) > self._high_water? (That would
230 # require keeping track of the number of bytes passed
231 # to a send() that hasn't finished yet.)
232 elif not self._buffer: # WRITING -> BACKED UP
233 # Make a mutable copy which we can extend.
234 self._buffer = bytearray(data)
235 self._maybe_pause_protocol()
236 else: # BACKED UP
237 # Append to buffer (also copies).
238 self._buffer.extend(data)
239 self._maybe_pause_protocol()
240
241 def _loop_writing(self, f=None, data=None):
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700242 try:
243 assert f is self._write_fut
244 self._write_fut = None
Victor Stinner915bcb02014-02-01 22:49:59 +0100245 self._pending_write = 0
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700246 if f:
247 f.result()
Guido van Rossumebb8e582013-12-04 12:12:07 -0800248 if data is None:
249 data = self._buffer
250 self._buffer = None
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700251 if not data:
252 if self._closing:
253 self._loop.call_soon(self._call_connection_lost, None)
254 if self._eof_written:
255 self._sock.shutdown(socket.SHUT_WR)
Victor Stinner915bcb02014-02-01 22:49:59 +0100256 # Now that we've reduced the buffer size, tell the
257 # protocol to resume writing if it was paused. Note that
258 # we do this last since the callback is called immediately
259 # and it may add more data to the buffer (even causing the
260 # protocol to be paused again).
261 self._maybe_resume_protocol()
Guido van Rossumebb8e582013-12-04 12:12:07 -0800262 else:
263 self._write_fut = self._loop._proactor.send(self._sock, data)
Victor Stinner915bcb02014-02-01 22:49:59 +0100264 if not self._write_fut.done():
265 assert self._pending_write == 0
266 self._pending_write = len(data)
267 self._write_fut.add_done_callback(self._loop_writing)
268 self._maybe_pause_protocol()
269 else:
270 self._write_fut.add_done_callback(self._loop_writing)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700271 except ConnectionResetError as exc:
272 self._force_close(exc)
273 except OSError as exc:
Victor Stinner0ee29c22014-02-19 01:40:41 +0100274 self._fatal_error(exc, 'Fatal write error on pipe transport')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700275
276 def can_write_eof(self):
277 return True
278
279 def write_eof(self):
280 self.close()
281
282 def abort(self):
283 self._force_close(None)
284
285
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100286class _ProactorWritePipeTransport(_ProactorBaseWritePipeTransport):
287 def __init__(self, *args, **kw):
288 super().__init__(*args, **kw)
289 self._read_fut = self._loop._proactor.recv(self._sock, 16)
290 self._read_fut.add_done_callback(self._pipe_closed)
291
292 def _pipe_closed(self, fut):
293 if fut.cancelled():
294 # the transport has been closed
295 return
Victor Stinner83bdfa02014-02-04 08:57:48 +0100296 assert fut.result() == b''
297 if self._closing:
298 assert self._read_fut is None
299 return
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100300 assert fut is self._read_fut, (fut, self._read_fut)
301 self._read_fut = None
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100302 if self._write_fut is not None:
Victor Stinner6f24d832014-02-20 10:33:01 +0100303 self._force_close(BrokenPipeError())
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100304 else:
305 self.close()
306
307
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700308class _ProactorDuplexPipeTransport(_ProactorReadPipeTransport,
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100309 _ProactorBaseWritePipeTransport,
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700310 transports.Transport):
311 """Transport for duplex pipes."""
312
313 def can_write_eof(self):
314 return False
315
316 def write_eof(self):
317 raise NotImplementedError
318
319
320class _ProactorSocketTransport(_ProactorReadPipeTransport,
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100321 _ProactorBaseWritePipeTransport,
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700322 transports.Transport):
323 """Transport for connected sockets."""
324
325 def _set_extra(self, sock):
326 self._extra['socket'] = sock
327 try:
328 self._extra['sockname'] = sock.getsockname()
329 except (socket.error, AttributeError):
Victor Stinnerb2614752014-08-25 23:20:52 +0200330 if self._loop.get_debug():
331 logger.warning("getsockname() failed on %r",
332 sock, exc_info=True)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700333 if 'peername' not in self._extra:
334 try:
335 self._extra['peername'] = sock.getpeername()
336 except (socket.error, AttributeError):
Victor Stinnerb2614752014-08-25 23:20:52 +0200337 if self._loop.get_debug():
338 logger.warning("getpeername() failed on %r",
339 sock, exc_info=True)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700340
341 def can_write_eof(self):
342 return True
343
344 def write_eof(self):
345 if self._closing or self._eof_written:
346 return
347 self._eof_written = True
348 if self._write_fut is None:
349 self._sock.shutdown(socket.SHUT_WR)
350
351
352class BaseProactorEventLoop(base_events.BaseEventLoop):
353
354 def __init__(self, proactor):
355 super().__init__()
Guido van Rossumfc29e0f2013-10-17 15:39:45 -0700356 logger.debug('Using proactor: %s', proactor.__class__.__name__)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700357 self._proactor = proactor
358 self._selector = proactor # convenient alias
Victor Stinner7de26462014-01-11 00:03:21 +0100359 self._self_reading_future = None
360 self._accept_futures = {} # socket file descriptor => Future
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700361 proactor.set_loop(self)
362 self._make_self_pipe()
363
364 def _make_socket_transport(self, sock, protocol, waiter=None,
365 extra=None, server=None):
366 return _ProactorSocketTransport(self, sock, protocol, waiter,
367 extra, server)
368
369 def _make_duplex_pipe_transport(self, sock, protocol, waiter=None,
370 extra=None):
371 return _ProactorDuplexPipeTransport(self,
372 sock, protocol, waiter, extra)
373
374 def _make_read_pipe_transport(self, sock, protocol, waiter=None,
375 extra=None):
376 return _ProactorReadPipeTransport(self, sock, protocol, waiter, extra)
377
378 def _make_write_pipe_transport(self, sock, protocol, waiter=None,
Victor Stinnerb60e9ca2014-01-31 14:18:18 +0100379 extra=None):
380 # We want connection_lost() to be called when other end closes
381 return _ProactorWritePipeTransport(self,
382 sock, protocol, waiter, extra)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700383
384 def close(self):
Victor Stinnerbb2fc5b2014-06-10 10:23:10 +0200385 if self.is_closed():
386 return
Victor Stinnerf328c7d2014-06-23 01:02:37 +0200387 super().close()
Victor Stinnerbb2fc5b2014-06-10 10:23:10 +0200388 self._stop_accept_futures()
389 self._close_self_pipe()
390 self._proactor.close()
391 self._proactor = None
392 self._selector = None
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700393
394 def sock_recv(self, sock, n):
395 return self._proactor.recv(sock, n)
396
397 def sock_sendall(self, sock, data):
398 return self._proactor.send(sock, data)
399
400 def sock_connect(self, sock, address):
Victor Stinner1b0580b2014-02-13 09:24:37 +0100401 try:
402 base_events._check_resolved_address(sock, address)
403 except ValueError as err:
404 fut = futures.Future(loop=self)
405 fut.set_exception(err)
406 return fut
407 else:
408 return self._proactor.connect(sock, address)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700409
410 def sock_accept(self, sock):
411 return self._proactor.accept(sock)
412
413 def _socketpair(self):
414 raise NotImplementedError
415
416 def _close_self_pipe(self):
Victor Stinner7de26462014-01-11 00:03:21 +0100417 if self._self_reading_future is not None:
418 self._self_reading_future.cancel()
419 self._self_reading_future = None
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700420 self._ssock.close()
421 self._ssock = None
422 self._csock.close()
423 self._csock = None
424 self._internal_fds -= 1
425
426 def _make_self_pipe(self):
427 # A self-socket, really. :-)
428 self._ssock, self._csock = self._socketpair()
429 self._ssock.setblocking(False)
430 self._csock.setblocking(False)
431 self._internal_fds += 1
Victor Stinnere912e652014-07-12 03:11:53 +0200432 # don't check the current loop because _make_self_pipe() is called
433 # from the event loop constructor
434 self._call_soon(self._loop_self_reading, (), check_loop=False)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700435
436 def _loop_self_reading(self, f=None):
437 try:
438 if f is not None:
439 f.result() # may raise
440 f = self._proactor.recv(self._ssock, 4096)
441 except:
442 self.close()
443 raise
444 else:
Victor Stinner7de26462014-01-11 00:03:21 +0100445 self._self_reading_future = f
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700446 f.add_done_callback(self._loop_self_reading)
447
448 def _write_to_self(self):
Victor Stinnerfe5649c2014-07-17 22:43:40 +0200449 self._csock.send(b'\0')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700450
451 def _start_serving(self, protocol_factory, sock, ssl=None, server=None):
Guido van Rossumebb8e582013-12-04 12:12:07 -0800452 if ssl:
453 raise ValueError('IocpEventLoop is incompatible with SSL.')
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700454
455 def loop(f=None):
456 try:
457 if f is not None:
458 conn, addr = f.result()
Victor Stinnere912e652014-07-12 03:11:53 +0200459 if self._debug:
460 logger.debug("%r got a new connection from %r: %r",
461 server, addr, conn)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700462 protocol = protocol_factory()
463 self._make_socket_transport(
464 conn, protocol,
465 extra={'peername': addr}, server=server)
Victor Stinnerbb2fc5b2014-06-10 10:23:10 +0200466 if self.is_closed():
467 return
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700468 f = self._proactor.accept(sock)
Yury Selivanov569efa22014-02-18 18:02:19 -0500469 except OSError as exc:
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700470 if sock.fileno() != -1:
Yury Selivanov569efa22014-02-18 18:02:19 -0500471 self.call_exception_handler({
Victor Stinnerb2614752014-08-25 23:20:52 +0200472 'message': 'Accept failed on a socket',
Yury Selivanov569efa22014-02-18 18:02:19 -0500473 'exception': exc,
474 'socket': sock,
475 })
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700476 sock.close()
Victor Stinnerb2614752014-08-25 23:20:52 +0200477 elif self._debug:
478 logger.debug("Accept failed on socket %r",
479 sock, exc_info=True)
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700480 except futures.CancelledError:
481 sock.close()
482 else:
Victor Stinner7de26462014-01-11 00:03:21 +0100483 self._accept_futures[sock.fileno()] = f
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700484 f.add_done_callback(loop)
485
486 self.call_soon(loop)
487
488 def _process_events(self, event_list):
489 pass # XXX hard work currently done in poll
490
Victor Stinnerbb2fc5b2014-06-10 10:23:10 +0200491 def _stop_accept_futures(self):
Victor Stinner7de26462014-01-11 00:03:21 +0100492 for future in self._accept_futures.values():
493 future.cancel()
Victor Stinnerbb2fc5b2014-06-10 10:23:10 +0200494 self._accept_futures.clear()
495
496 def _stop_serving(self, sock):
497 self._stop_accept_futures()
Guido van Rossum27b7c7e2013-10-17 13:40:50 -0700498 self._proactor._stop_serving(sock)
499 sock.close()