Skip to content

Commit 9c18a74

Browse files
authored
Use multiprocessing start_method "forkserver" (#4306)
* Use `multiprocessing` `start_method` `"forkserver"` Alternative to PR #4305 * Add link to comment under PR #4105 * Unconditionally `pytest.skip("DEADLOCK")` for PyPy Windows * Remove `SKIP_IF_DEADLOCK` entirely, for simplicity. Hopefully this PR will resolve the deadlocks for good. * Add "In a nutshell" comment, in response to request by @EricCousineau-TRI
1 parent 4894922 commit 9c18a74

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

tests/conftest.py

+12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import contextlib
88
import difflib
99
import gc
10+
import multiprocessing
11+
import os
1012
import re
1113
import textwrap
1214

@@ -15,6 +17,16 @@
1517
# Early diagnostic for failed imports
1618
import pybind11_tests
1719

20+
if os.name != "nt":
21+
# Full background: https://github.com/pybind/pybind11/issues/4105#issuecomment-1301004592
22+
# In a nutshell: fork() after starting threads == flakiness in the form of deadlocks.
23+
# It is actually a well-known pitfall, unfortunately without guard rails.
24+
# "forkserver" is more performant than "spawn" (~9s vs ~13s for tests/test_gil_scoped.py,
25+
# visit the issuecomment link above for details).
26+
# Windows does not have fork() and the associated pitfall, therefore it is best left
27+
# running with defaults.
28+
multiprocessing.set_start_method("forkserver")
29+
1830
_long_marker = re.compile(r"([0-9])L")
1931
_hexadecimal = re.compile(r"0x[0-9a-fA-F]+")
2032

tests/test_gil_scoped.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import pytest
77

8+
import env
89
from pybind11_tests import gil_scoped as m
910

1011

@@ -144,7 +145,6 @@ def _intentional_deadlock():
144145

145146

146147
ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK = ALL_BASIC_TESTS + (_intentional_deadlock,)
147-
SKIP_IF_DEADLOCK = True # See PR #4216
148148

149149

150150
def _run_in_process(target, *args, **kwargs):
@@ -181,7 +181,7 @@ def _run_in_process(target, *args, **kwargs):
181181
elif process.exitcode is None:
182182
assert t_delta > 0.9 * timeout
183183
msg = "DEADLOCK, most likely, exactly what this test is meant to detect."
184-
if SKIP_IF_DEADLOCK:
184+
if env.PYPY and env.WIN:
185185
pytest.skip(msg)
186186
raise RuntimeError(msg)
187187
return process.exitcode

0 commit comments

Comments
 (0)