test_gil_scoped.py revision 14299
16019Shines@cs.fsu.eduimport multiprocessing
26019Shines@cs.fsu.eduimport threading
37178Sgblack@eecs.umich.edufrom pybind11_tests import gil_scoped as m
47178Sgblack@eecs.umich.edu
57178Sgblack@eecs.umich.edu
67178Sgblack@eecs.umich.edudef _run_in_process(target, *args, **kwargs):
77178Sgblack@eecs.umich.edu    """Runs target in process and returns its exitcode after 10s (None if still alive)."""
87178Sgblack@eecs.umich.edu    process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)
97178Sgblack@eecs.umich.edu    process.daemon = True
107178Sgblack@eecs.umich.edu    try:
117178Sgblack@eecs.umich.edu        process.start()
127178Sgblack@eecs.umich.edu        # Do not need to wait much, 10s should be more than enough.
137178Sgblack@eecs.umich.edu        process.join(timeout=10)
147178Sgblack@eecs.umich.edu        return process.exitcode
156019Shines@cs.fsu.edu    finally:
166019Shines@cs.fsu.edu        if process.is_alive():
176019Shines@cs.fsu.edu            process.terminate()
186019Shines@cs.fsu.edu
196019Shines@cs.fsu.edu
206019Shines@cs.fsu.edudef _python_to_cpp_to_python():
216019Shines@cs.fsu.edu    """Calls different C++ functions that come back to Python."""
226019Shines@cs.fsu.edu    class ExtendedVirtClass(m.VirtClass):
236019Shines@cs.fsu.edu        def virtual_func(self):
246019Shines@cs.fsu.edu            pass
256019Shines@cs.fsu.edu
266019Shines@cs.fsu.edu        def pure_virtual_func(self):
276019Shines@cs.fsu.edu            pass
286019Shines@cs.fsu.edu
296019Shines@cs.fsu.edu    extended = ExtendedVirtClass()
306019Shines@cs.fsu.edu    m.test_callback_py_obj(lambda: None)
316019Shines@cs.fsu.edu    m.test_callback_std_func(lambda: None)
326019Shines@cs.fsu.edu    m.test_callback_virtual_func(extended)
336019Shines@cs.fsu.edu    m.test_callback_pure_virtual_func(extended)
346019Shines@cs.fsu.edu
356019Shines@cs.fsu.edu
366019Shines@cs.fsu.edudef _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
376019Shines@cs.fsu.edu    """Calls different C++ functions that come back to Python, from Python threads."""
386019Shines@cs.fsu.edu    threads = []
396019Shines@cs.fsu.edu    for _ in range(num_threads):
406019Shines@cs.fsu.edu        thread = threading.Thread(target=_python_to_cpp_to_python)
416019Shines@cs.fsu.edu        thread.daemon = True
426019Shines@cs.fsu.edu        thread.start()
436019Shines@cs.fsu.edu        if parallel:
446019Shines@cs.fsu.edu            threads.append(thread)
456019Shines@cs.fsu.edu        else:
466019Shines@cs.fsu.edu            thread.join()
476019Shines@cs.fsu.edu    for thread in threads:
486019Shines@cs.fsu.edu        thread.join()
496019Shines@cs.fsu.edu
506019Shines@cs.fsu.edu
516019Shines@cs.fsu.edudef test_python_to_cpp_to_python_from_thread():
526019Shines@cs.fsu.edu    """Makes sure there is no GIL deadlock when running in a thread.
536019Shines@cs.fsu.edu
546019Shines@cs.fsu.edu    It runs in a separate process to be able to stop and assert if it deadlocks.
556019Shines@cs.fsu.edu    """
566019Shines@cs.fsu.edu    assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0
576019Shines@cs.fsu.edu
586243Sgblack@eecs.umich.edu
596243Sgblack@eecs.umich.edudef test_python_to_cpp_to_python_from_thread_multiple_parallel():
606243Sgblack@eecs.umich.edu    """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.
616243Sgblack@eecs.umich.edu
626243Sgblack@eecs.umich.edu    It runs in a separate process to be able to stop and assert if it deadlocks.
636019Shines@cs.fsu.edu    """
646019Shines@cs.fsu.edu    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0
656019Shines@cs.fsu.edu
666019Shines@cs.fsu.edu
676019Shines@cs.fsu.edudef test_python_to_cpp_to_python_from_thread_multiple_sequential():
686019Shines@cs.fsu.edu    """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.
696019Shines@cs.fsu.edu
706019Shines@cs.fsu.edu    It runs in a separate process to be able to stop and assert if it deadlocks.
716019Shines@cs.fsu.edu    """
726019Shines@cs.fsu.edu    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0
736019Shines@cs.fsu.edu
746019Shines@cs.fsu.edu
756019Shines@cs.fsu.edudef test_python_to_cpp_to_python_from_process():
766019Shines@cs.fsu.edu    """Makes sure there is no GIL deadlock when using processes.
776019Shines@cs.fsu.edu
786019Shines@cs.fsu.edu    This test is for completion, but it was never an issue.
796019Shines@cs.fsu.edu    """
806019Shines@cs.fsu.edu    assert _run_in_process(_python_to_cpp_to_python) == 0
816019Shines@cs.fsu.edu
826019Shines@cs.fsu.edu
836019Shines@cs.fsu.edudef test_cross_module_gil():
846019Shines@cs.fsu.edu    """Makes sure that the GIL can be acquired by another module from a GIL-released state."""
856019Shines@cs.fsu.edu    m.test_cross_module_gil()  # Should not raise a SIGSEGV
866019Shines@cs.fsu.edu