Add fallback implementation of PyCriticalSection_BeginMutex for Python 3.13t (#5981)

* Add failback implementation of `PyCriticalSection_BeginMutex` for Python 3.13t

* Add comment for Python version

* Use `_PyCriticalSection_BeginSlow`

* Add forward declaration

* Fix forward declaration

* Remove always true condition `defined(PY_VERSION_HEX)`

* Detect musllinux

* Add manylinux test

* Use direct mutex locking for Python 3.13t

`_PyCriticalSection_BeginSlow` is a private CPython function not exported
on Linux. For Python < 3.14.0rc1, use direct `mutex.lock()`/`mutex.unlock()`
instead of critical section APIs.

* Empty commit to trigger CI

* Empty commit to trigger CI

* Empty commit to trigger CI

* Run apt update before apt install

* Remove unnecessary prefix

* Add manylinux test with Python 3.13t

* Simplify pycritical_section with std::unique_lock fallback for Python < 3.14

* Fix potential deadlock in make_iterator_impl for Python 3.13t

Refactor pycritical_section into a unified class with internal version
checks instead of using a type alias fallback. Skip locking in
make_iterator_impl for Python < 3.14.0rc1 to avoid deadlock during
type registration, as pycritical_section cannot release the mutex
during Python callbacks without PyCriticalSection_BeginMutex.

* Add reference for xfail message
This commit is contained in:
Xuehai Pan
2026-02-10 13:14:07 +08:00
committed by GitHub
parent 5f2c678916
commit 3ae5a173c5
6 changed files with 52 additions and 5 deletions

View File

@@ -11,6 +11,18 @@ MACOS = sys.platform.startswith("darwin")
WIN = sys.platform.startswith("win32") or sys.platform.startswith("cygwin")
FREEBSD = sys.platform.startswith("freebsd")
MUSLLINUX = False
MANYLINUX = False
if LINUX:
def _is_musl() -> bool:
libc, _ = platform.libc_ver()
return libc == "musl" or (libc != "glibc" and libc != "")
MUSLLINUX = _is_musl()
MANYLINUX = not MUSLLINUX
del _is_musl
CPYTHON = platform.python_implementation() == "CPython"
PYPY = platform.python_implementation() == "PyPy"
GRAALPY = sys.implementation.name == "graalpy"

View File

@@ -408,6 +408,11 @@ def test_import_in_subinterpreter_before_main():
@pytest.mark.skipif(
sys.platform.startswith("emscripten"), reason="Requires loadable modules"
)
@pytest.mark.xfail(
env.MUSLLINUX,
reason="Flaky on musllinux, see also: https://github.com/pybind/pybind11/pull/5972#discussion_r2755283335",
strict=False,
)
@pytest.mark.skipif(not CONCURRENT_INTERPRETERS_SUPPORT, reason="Requires 3.14.0b3+")
def test_import_in_subinterpreter_concurrently():
"""Tests that importing a module in multiple subinterpreters concurrently works correctly"""