Skip to content

Commit

Permalink
Use multiprocessing start_method "forkserver" (#4306)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Ralf W. Grosse-Kunstleve authored Nov 23, 2022
1 parent 4894922 commit 9c18a74
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
12 changes: 12 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import contextlib
import difflib
import gc
import multiprocessing
import os
import re
import textwrap

Expand All @@ -15,6 +17,16 @@
# Early diagnostic for failed imports
import pybind11_tests

if os.name != "nt":
# Full background: https://github.com/pybind/pybind11/issues/4105#issuecomment-1301004592
# In a nutshell: fork() after starting threads == flakiness in the form of deadlocks.
# It is actually a well-known pitfall, unfortunately without guard rails.
# "forkserver" is more performant than "spawn" (~9s vs ~13s for tests/test_gil_scoped.py,
# visit the issuecomment link above for details).
# Windows does not have fork() and the associated pitfall, therefore it is best left
# running with defaults.
multiprocessing.set_start_method("forkserver")

_long_marker = re.compile(r"([0-9])L")
_hexadecimal = re.compile(r"0x[0-9a-fA-F]+")

Expand Down
4 changes: 2 additions & 2 deletions tests/test_gil_scoped.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import pytest

import env
from pybind11_tests import gil_scoped as m


Expand Down Expand Up @@ -144,7 +145,6 @@ def _intentional_deadlock():


ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK = ALL_BASIC_TESTS + (_intentional_deadlock,)
SKIP_IF_DEADLOCK = True # See PR #4216


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

0 comments on commit 9c18a74

Please sign in to comment.