From 99b6011e56471c6f9c017b6fb3edcc64430b01f8 Mon Sep 17 00:00:00 2001 From: Jiucheng Zang Date: Sat, 20 Jun 2026 02:03:31 -0400 Subject: [PATCH 1/2] gh-151644: Fix data race in sys.setdlopenflags/getdlopenflags under free-threading In free-threading builds, concurrent calls to sys.getdlopenflags() and sys.setdlopenflags() race on interp->imports.dlopenflags. Fix by using FT_ATOMIC_LOAD_INT_RELAXED / FT_ATOMIC_STORE_INT_RELAXED in _PyImport_GetDLOpenFlags and _PyImport_SetDLOpenFlags, consistent with how analogous interpreter-state integer fields (lazy_imports_mode, pystats_enabled) are protected. Relaxed ordering is correct here: dlopenflags is a standalone config integer with no ordering relationship to other memory. Co-Authored-By: Claude Sonnet 4.6 --- Lib/test/test_free_threading/test_sys.py | 21 +++++++++++++++++++ .../2026-06-18-gh-issue-151644.rst | 4 ++++ Python/import.c | 4 ++-- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-gh-issue-151644.rst diff --git a/Lib/test/test_free_threading/test_sys.py b/Lib/test/test_free_threading/test_sys.py index 37b53bd723fd767..271fdd13c62b668 100644 --- a/Lib/test/test_free_threading/test_sys.py +++ b/Lib/test/test_free_threading/test_sys.py @@ -4,6 +4,27 @@ class SysModuleTest(unittest.TestCase): + @unittest.skipUnless(hasattr(sys, "setdlopenflags"), + "test needs sys.setdlopenflags()") + def test_dlopenflags_concurrent(self): + # gh-151644: getdlopenflags() and setdlopenflags() must be safe to + # call concurrently in free-threaded builds. + original = sys.getdlopenflags() + self.addCleanup(sys.setdlopenflags, original) + + # Use a small set of known-valid flag values to avoid integer overflow. + flag_values = [1, 2, 256, 257] + + def worker(worker_id): + for i in range(20_000): + if worker_id % 2 == 0: + sys.getdlopenflags() + else: + sys.setdlopenflags(flag_values[worker_id % len(flag_values)]) + + workers = [lambda i=i: worker(i) for i in range(6)] + threading_helper.run_concurrently(workers) + def test_int_max_str_digits_thread(self): # gh-151218: Check that it's safe to call get_int_max_str_digits() and # set_int_max_str_digits() in parallel. Previously, this test triggered diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-gh-issue-151644.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-gh-issue-151644.rst new file mode 100644 index 000000000000000..ff5058e14b42f15 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-gh-issue-151644.rst @@ -0,0 +1,4 @@ +Fix a data race in :func:`sys.setdlopenflags` and :func:`sys.getdlopenflags` +when called concurrently in the free-threaded build. The underlying +``_PyImport_GetDLOpenFlags`` and ``_PyImport_SetDLOpenFlags`` functions now +use atomic load/store operations. diff --git a/Python/import.c b/Python/import.c index 6da6faf5f28cc3b..ae44ebc5c01a39d 100644 --- a/Python/import.c +++ b/Python/import.c @@ -908,13 +908,13 @@ _PyImport_SwapPackageContext(const char *newcontext) int _PyImport_GetDLOpenFlags(PyInterpreterState *interp) { - return DLOPENFLAGS(interp); + return FT_ATOMIC_LOAD_INT_RELAXED(DLOPENFLAGS(interp)); } void _PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val) { - DLOPENFLAGS(interp) = new_val; + FT_ATOMIC_STORE_INT_RELAXED(DLOPENFLAGS(interp), new_val); } #endif // HAVE_DLOPEN From f75b2c7a4aa7dc349ca326b47bb2d9826ac9896b Mon Sep 17 00:00:00 2001 From: Jiucheng Zang Date: Sat, 20 Jun 2026 02:15:09 -0400 Subject: [PATCH 2/2] Misc/NEWS.d: fix news entry filename format for gh-151644 Co-Authored-By: Claude Sonnet 4.6 --- ...-151644.rst => 2026-06-18-00-00-00.gh-issue-151644.5cFffN.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Misc/NEWS.d/next/Core_and_Builtins/{2026-06-18-gh-issue-151644.rst => 2026-06-18-00-00-00.gh-issue-151644.5cFffN.rst} (100%) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-gh-issue-151644.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-00-00-00.gh-issue-151644.5cFffN.rst similarity index 100% rename from Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-gh-issue-151644.rst rename to Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-00-00-00.gh-issue-151644.5cFffN.rst