test_gil_scoped.py revision 14299:2fbea9df56d2
15347Ssaidi@eecs.umich.eduimport multiprocessing
23395Shsul@eecs.umich.eduimport threading
33395Shsul@eecs.umich.edufrom pybind11_tests import gil_scoped as m
43395Shsul@eecs.umich.edu
53395Shsul@eecs.umich.edu
63395Shsul@eecs.umich.edudef _run_in_process(target, *args, **kwargs):
73395Shsul@eecs.umich.edu    """Runs target in process and returns its exitcode after 10s (None if still alive)."""
83395Shsul@eecs.umich.edu    process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)
93395Shsul@eecs.umich.edu    process.daemon = True
103395Shsul@eecs.umich.edu    try:
113395Shsul@eecs.umich.edu        process.start()
123395Shsul@eecs.umich.edu        # Do not need to wait much, 10s should be more than enough.
133395Shsul@eecs.umich.edu        process.join(timeout=10)
143395Shsul@eecs.umich.edu        return process.exitcode
153395Shsul@eecs.umich.edu    finally:
163395Shsul@eecs.umich.edu        if process.is_alive():
173395Shsul@eecs.umich.edu            process.terminate()
183395Shsul@eecs.umich.edu
193395Shsul@eecs.umich.edu
203395Shsul@eecs.umich.edudef _python_to_cpp_to_python():
213395Shsul@eecs.umich.edu    """Calls different C++ functions that come back to Python."""
223395Shsul@eecs.umich.edu    class ExtendedVirtClass(m.VirtClass):
233395Shsul@eecs.umich.edu        def virtual_func(self):
243395Shsul@eecs.umich.edu            pass
253395Shsul@eecs.umich.edu
263395Shsul@eecs.umich.edu        def pure_virtual_func(self):
273395Shsul@eecs.umich.edu            pass
283395Shsul@eecs.umich.edu
293395Shsul@eecs.umich.edu    extended = ExtendedVirtClass()
303509Shsul@eecs.umich.edu    m.test_callback_py_obj(lambda: None)
316654Snate@binkert.org    m.test_callback_std_func(lambda: None)
323395Shsul@eecs.umich.edu    m.test_callback_virtual_func(extended)
336654Snate@binkert.org    m.test_callback_pure_virtual_func(extended)
343395Shsul@eecs.umich.edu
356654Snate@binkert.org
366654Snate@binkert.orgdef _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
376654Snate@binkert.org    """Calls different C++ functions that come back to Python, from Python threads."""
383395Shsul@eecs.umich.edu    threads = []
393481Shsul@eecs.umich.edu    for _ in range(num_threads):
403481Shsul@eecs.umich.edu        thread = threading.Thread(target=_python_to_cpp_to_python)
413481Shsul@eecs.umich.edu        thread.daemon = True
423481Shsul@eecs.umich.edu        thread.start()
435347Ssaidi@eecs.umich.edu        if parallel:
443481Shsul@eecs.umich.edu            threads.append(thread)
453681Sktlim@umich.edu        else:
463681Sktlim@umich.edu            thread.join()
473681Sktlim@umich.edu    for thread in threads:
485347Ssaidi@eecs.umich.edu        thread.join()
495869Sksewell@umich.edu
505869Sksewell@umich.edu
515869Sksewell@umich.edudef test_python_to_cpp_to_python_from_thread():
525869Sksewell@umich.edu    """Makes sure there is no GIL deadlock when running in a thread.
535869Sksewell@umich.edu
543481Shsul@eecs.umich.edu    It runs in a separate process to be able to stop and assert if it deadlocks.
555347Ssaidi@eecs.umich.edu    """
563481Shsul@eecs.umich.edu    assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0
573481Shsul@eecs.umich.edu
583481Shsul@eecs.umich.edu
593481Shsul@eecs.umich.edudef test_python_to_cpp_to_python_from_thread_multiple_parallel():
603481Shsul@eecs.umich.edu    """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.
613481Shsul@eecs.umich.edu
625369Ssaidi@eecs.umich.edu    It runs in a separate process to be able to stop and assert if it deadlocks.
633481Shsul@eecs.umich.edu    """
645347Ssaidi@eecs.umich.edu    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0
653481Shsul@eecs.umich.edu
663481Shsul@eecs.umich.edu
673481Shsul@eecs.umich.edudef test_python_to_cpp_to_python_from_thread_multiple_sequential():
683481Shsul@eecs.umich.edu    """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.
693481Shsul@eecs.umich.edu
703481Shsul@eecs.umich.edu    It runs in a separate process to be able to stop and assert if it deadlocks.
713481Shsul@eecs.umich.edu    """
723395Shsul@eecs.umich.edu    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0
733395Shsul@eecs.umich.edu
743395Shsul@eecs.umich.edu
754167Sbinkertn@umich.edudef test_python_to_cpp_to_python_from_process():
763395Shsul@eecs.umich.edu    """Makes sure there is no GIL deadlock when using processes.
773395Shsul@eecs.umich.edu
783395Shsul@eecs.umich.edu    This test is for completion, but it was never an issue.
793511Shsul@eecs.umich.edu    """
803395Shsul@eecs.umich.edu    assert _run_in_process(_python_to_cpp_to_python) == 0
813395Shsul@eecs.umich.edu
823395Shsul@eecs.umich.edu
835211Ssaidi@eecs.umich.edudef test_cross_module_gil():
845211Ssaidi@eecs.umich.edu    """Makes sure that the GIL can be acquired by another module from a GIL-released state."""
853395Shsul@eecs.umich.edu    m.test_cross_module_gil()  # Should not raise a SIGSEGV
863395Shsul@eecs.umich.edu