gh-137583: Only lock the SSL context, not the SSL socket (GH-137588)
Some checks are pending
Tests / Cross build Linux (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / Ubuntu SSL tests with AWS-LC (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Sanitizers (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run

Fixes a deadlock in 3.13.6.
This commit is contained in:
Peter Bierma 2025-08-10 10:47:11 -04:00 committed by GitHub
parent 046a4e39b3
commit 55788a9096
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 19 deletions

View file

@ -4627,6 +4627,42 @@ class ThreadedTests(unittest.TestCase):
with client_context.wrap_socket(socket.socket()) as s:
s.connect((HOST, server.port))
def test_thread_recv_while_main_thread_sends(self):
# GH-137583: Locking was added to calls to send() and recv() on SSL
# socket objects. This seemed fine at the surface level because those
# calls weren't re-entrant, but recv() calls would implicitly mimick
# holding a lock by blocking until it received data. This means that
# if a thread started to infinitely block until data was received, calls
# to send() would deadlock, because it would wait forever on the lock
# that the recv() call held.
data = b"1" * 1024
event = threading.Event()
def background(sock):
event.set()
received = sock.recv(len(data))
self.assertEqual(received, data)
client_context, server_context, hostname = testing_context()
server = ThreadedEchoServer(context=server_context)
with server:
with client_context.wrap_socket(socket.socket(),
server_hostname=hostname) as sock:
sock.connect((HOST, server.port))
sock.settimeout(1)
sock.setblocking(1)
# Ensure that the server is ready to accept requests
sock.sendall(b"123")
self.assertEqual(sock.recv(3), b"123")
with threading_helper.catch_threading_exception() as cm:
thread = threading.Thread(target=background,
args=(sock,), daemon=True)
thread.start()
event.wait()
sock.sendall(data)
thread.join()
if cm.exc_value is not None:
raise cm.exc_value
@unittest.skipUnless(has_tls_version('TLSv1_3') and ssl.HAS_PHA,
"Test needs TLS 1.3 PHA")