mirror of
https://github.com/python/cpython.git
synced 2026-04-18 18:01:02 +00:00
[3.13] gh-126500: test_ssl: Don't stop ThreadedEchoServer on OSError in ConnectionHandler; rely on __exit__ (GH-126503) (GH-126571)
gh-126500: test_ssl: Don't stop ThreadedEchoServer on OSError in ConnectionHandler; rely on __exit__ (GH-126503) If `read()` in the ConnectionHandler thread raises `OSError` (except `ConnectionError`), the ConnectionHandler shuts down the entire ThreadedEchoServer, preventing further connections. It also does that for `EPROTOTYPE` in `wrap_conn`. As far as I can see, this is done to avoid the server thread getting stuck, forgotten, in its accept loop. However, since 2011 (5b95eb90a7) the server is used as a context manager, and its `__exit__` does `stop()` and `join()`. (I'm not sure if we *always* used `with` since that commit, but currently we do.) Make sure that the context manager *is* used, and remove the `server.stop()` calls from ConnectionHandler. (cherry picked from commitc9cda1608e) Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
parent
1e4b9c7fae
commit
fc10908f7d
1 changed files with 12 additions and 5 deletions
|
|
@ -2312,7 +2312,6 @@ def wrap_conn(self):
|
|||
# See also http://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/
|
||||
if e.errno != errno.EPROTOTYPE and sys.platform != "darwin":
|
||||
self.running = False
|
||||
self.server.stop()
|
||||
self.close()
|
||||
return False
|
||||
else:
|
||||
|
|
@ -2449,10 +2448,6 @@ def run(self):
|
|||
self.close()
|
||||
self.running = False
|
||||
|
||||
# normally, we'd just stop here, but for the test
|
||||
# harness, we want to stop the server
|
||||
self.server.stop()
|
||||
|
||||
def __init__(self, certificate=None, ssl_version=None,
|
||||
certreqs=None, cacerts=None,
|
||||
chatty=True, connectionchatty=False, starttls_server=False,
|
||||
|
|
@ -2486,21 +2481,33 @@ def __init__(self, certificate=None, ssl_version=None,
|
|||
self.conn_errors = []
|
||||
threading.Thread.__init__(self)
|
||||
self.daemon = True
|
||||
self._in_context = False
|
||||
|
||||
def __enter__(self):
|
||||
if self._in_context:
|
||||
raise ValueError('Re-entering ThreadedEchoServer context')
|
||||
self._in_context = True
|
||||
self.start(threading.Event())
|
||||
self.flag.wait()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
assert self._in_context
|
||||
self._in_context = False
|
||||
self.stop()
|
||||
self.join()
|
||||
|
||||
def start(self, flag=None):
|
||||
if not self._in_context:
|
||||
raise ValueError(
|
||||
'ThreadedEchoServer must be used as a context manager')
|
||||
self.flag = flag
|
||||
threading.Thread.start(self)
|
||||
|
||||
def run(self):
|
||||
if not self._in_context:
|
||||
raise ValueError(
|
||||
'ThreadedEchoServer must be used as a context manager')
|
||||
self.sock.settimeout(1.0)
|
||||
self.sock.listen(5)
|
||||
self.active = True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue