gh-126907: make atexit thread safe in free-threading (#127935)

Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Peter Bierma 2024-12-16 14:31:44 -05:00 committed by GitHub
parent 4937ba54c0
commit 3b766824fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 127 additions and 89 deletions

View file

@ -4,7 +4,7 @@ import textwrap
import unittest
from test import support
from test.support import script_helper
from test.support import threading_helper
class GeneralTest(unittest.TestCase):
def test_general(self):
@ -46,6 +46,39 @@ class FunctionalTest(unittest.TestCase):
self.assertEqual(res.out.decode().splitlines(), ["atexit2", "atexit1"])
self.assertFalse(res.err)
@threading_helper.requires_working_threading()
@support.requires_resource("cpu")
@unittest.skipUnless(support.Py_GIL_DISABLED, "only meaningful without the GIL")
def test_atexit_thread_safety(self):
# GH-126907: atexit was not thread safe on the free-threaded build
source = """
from threading import Thread
def dummy():
pass
def thready():
for _ in range(100):
atexit.register(dummy)
atexit._clear()
atexit.register(dummy)
atexit.unregister(dummy)
atexit._run_exitfuncs()
threads = [Thread(target=thready) for _ in range(10)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
"""
# atexit._clear() has some evil side effects, and we don't
# want them to affect the rest of the tests.
script_helper.assert_python_ok("-c", textwrap.dedent(source))
@support.cpython_only
class SubinterpreterTest(unittest.TestCase):