Blame external/pybind11/tests/test_gil_scoped.py

Packit 534379
import multiprocessing
Packit 534379
import threading
Packit 534379
from pybind11_tests import gil_scoped as m
Packit 534379
Packit 534379
Packit 534379
def _run_in_process(target, *args, **kwargs):
Packit 534379
    """Runs target in process and returns its exitcode after 10s (None if still alive)."""
Packit 534379
    process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)
Packit 534379
    process.daemon = True
Packit 534379
    try:
Packit 534379
        process.start()
Packit 534379
        # Do not need to wait much, 10s should be more than enough.
Packit 534379
        process.join(timeout=10)
Packit 534379
        return process.exitcode
Packit 534379
    finally:
Packit 534379
        if process.is_alive():
Packit 534379
            process.terminate()
Packit 534379
Packit 534379
Packit 534379
def _python_to_cpp_to_python():
Packit 534379
    """Calls different C++ functions that come back to Python."""
Packit 534379
    class ExtendedVirtClass(m.VirtClass):
Packit 534379
        def virtual_func(self):
Packit 534379
            pass
Packit 534379
Packit 534379
        def pure_virtual_func(self):
Packit 534379
            pass
Packit 534379
Packit 534379
    extended = ExtendedVirtClass()
Packit 534379
    m.test_callback_py_obj(lambda: None)
Packit 534379
    m.test_callback_std_func(lambda: None)
Packit 534379
    m.test_callback_virtual_func(extended)
Packit 534379
    m.test_callback_pure_virtual_func(extended)
Packit 534379
Packit 534379
Packit 534379
def _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
Packit 534379
    """Calls different C++ functions that come back to Python, from Python threads."""
Packit 534379
    threads = []
Packit 534379
    for _ in range(num_threads):
Packit 534379
        thread = threading.Thread(target=_python_to_cpp_to_python)
Packit 534379
        thread.daemon = True
Packit 534379
        thread.start()
Packit 534379
        if parallel:
Packit 534379
            threads.append(thread)
Packit 534379
        else:
Packit 534379
            thread.join()
Packit 534379
    for thread in threads:
Packit 534379
        thread.join()
Packit 534379
Packit 534379
Packit 534379
def test_python_to_cpp_to_python_from_thread():
Packit 534379
    """Makes sure there is no GIL deadlock when running in a thread.
Packit 534379
Packit 534379
    It runs in a separate process to be able to stop and assert if it deadlocks.
Packit 534379
    """
Packit 534379
    assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0
Packit 534379
Packit 534379
Packit 534379
def test_python_to_cpp_to_python_from_thread_multiple_parallel():
Packit 534379
    """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.
Packit 534379
Packit 534379
    It runs in a separate process to be able to stop and assert if it deadlocks.
Packit 534379
    """
Packit 534379
    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0
Packit 534379
Packit 534379
Packit 534379
def test_python_to_cpp_to_python_from_thread_multiple_sequential():
Packit 534379
    """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.
Packit 534379
Packit 534379
    It runs in a separate process to be able to stop and assert if it deadlocks.
Packit 534379
    """
Packit 534379
    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0
Packit 534379
Packit 534379
Packit 534379
def test_python_to_cpp_to_python_from_process():
Packit 534379
    """Makes sure there is no GIL deadlock when using processes.
Packit 534379
Packit 534379
    This test is for completion, but it was never an issue.
Packit 534379
    """
Packit 534379
    assert _run_in_process(_python_to_cpp_to_python) == 0
Packit 534379
Packit 534379
Packit 534379
def test_cross_module_gil():
Packit 534379
    """Makes sure that the GIL can be acquired by another module from a GIL-released state."""
Packit 534379
    m.test_cross_module_gil()  # Should not raise a SIGSEGV