114299Sbbruce@ucdavis.eduimport multiprocessing 214299Sbbruce@ucdavis.eduimport threading 314299Sbbruce@ucdavis.edufrom pybind11_tests import gil_scoped as m 414299Sbbruce@ucdavis.edu 514299Sbbruce@ucdavis.edu 614299Sbbruce@ucdavis.edudef _run_in_process(target, *args, **kwargs): 714299Sbbruce@ucdavis.edu """Runs target in process and returns its exitcode after 10s (None if still alive).""" 814299Sbbruce@ucdavis.edu process = multiprocessing.Process(target=target, args=args, kwargs=kwargs) 914299Sbbruce@ucdavis.edu process.daemon = True 1014299Sbbruce@ucdavis.edu try: 1114299Sbbruce@ucdavis.edu process.start() 1214299Sbbruce@ucdavis.edu # Do not need to wait much, 10s should be more than enough. 1314299Sbbruce@ucdavis.edu process.join(timeout=10) 1414299Sbbruce@ucdavis.edu return process.exitcode 1514299Sbbruce@ucdavis.edu finally: 1614299Sbbruce@ucdavis.edu if process.is_alive(): 1714299Sbbruce@ucdavis.edu process.terminate() 1814299Sbbruce@ucdavis.edu 1914299Sbbruce@ucdavis.edu 2014299Sbbruce@ucdavis.edudef _python_to_cpp_to_python(): 2114299Sbbruce@ucdavis.edu """Calls different C++ functions that come back to Python.""" 2214299Sbbruce@ucdavis.edu class ExtendedVirtClass(m.VirtClass): 2314299Sbbruce@ucdavis.edu def virtual_func(self): 2414299Sbbruce@ucdavis.edu pass 2514299Sbbruce@ucdavis.edu 2614299Sbbruce@ucdavis.edu def pure_virtual_func(self): 2714299Sbbruce@ucdavis.edu pass 2814299Sbbruce@ucdavis.edu 2914299Sbbruce@ucdavis.edu extended = ExtendedVirtClass() 3014299Sbbruce@ucdavis.edu m.test_callback_py_obj(lambda: None) 3114299Sbbruce@ucdavis.edu m.test_callback_std_func(lambda: None) 3214299Sbbruce@ucdavis.edu m.test_callback_virtual_func(extended) 3314299Sbbruce@ucdavis.edu m.test_callback_pure_virtual_func(extended) 3414299Sbbruce@ucdavis.edu 3514299Sbbruce@ucdavis.edu 3614299Sbbruce@ucdavis.edudef _python_to_cpp_to_python_from_threads(num_threads, parallel=False): 3714299Sbbruce@ucdavis.edu """Calls different C++ functions that come back to Python, from Python threads.""" 3814299Sbbruce@ucdavis.edu threads = [] 3914299Sbbruce@ucdavis.edu for _ in range(num_threads): 4014299Sbbruce@ucdavis.edu thread = threading.Thread(target=_python_to_cpp_to_python) 4114299Sbbruce@ucdavis.edu thread.daemon = True 4214299Sbbruce@ucdavis.edu thread.start() 4314299Sbbruce@ucdavis.edu if parallel: 4414299Sbbruce@ucdavis.edu threads.append(thread) 4514299Sbbruce@ucdavis.edu else: 4614299Sbbruce@ucdavis.edu thread.join() 4714299Sbbruce@ucdavis.edu for thread in threads: 4814299Sbbruce@ucdavis.edu thread.join() 4914299Sbbruce@ucdavis.edu 5014299Sbbruce@ucdavis.edu 5114299Sbbruce@ucdavis.edudef test_python_to_cpp_to_python_from_thread(): 5214299Sbbruce@ucdavis.edu """Makes sure there is no GIL deadlock when running in a thread. 5314299Sbbruce@ucdavis.edu 5414299Sbbruce@ucdavis.edu It runs in a separate process to be able to stop and assert if it deadlocks. 5514299Sbbruce@ucdavis.edu """ 5614299Sbbruce@ucdavis.edu assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0 5714299Sbbruce@ucdavis.edu 5814299Sbbruce@ucdavis.edu 5914299Sbbruce@ucdavis.edudef test_python_to_cpp_to_python_from_thread_multiple_parallel(): 6014299Sbbruce@ucdavis.edu """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel. 6114299Sbbruce@ucdavis.edu 6214299Sbbruce@ucdavis.edu It runs in a separate process to be able to stop and assert if it deadlocks. 6314299Sbbruce@ucdavis.edu """ 6414299Sbbruce@ucdavis.edu assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0 6514299Sbbruce@ucdavis.edu 6614299Sbbruce@ucdavis.edu 6714299Sbbruce@ucdavis.edudef test_python_to_cpp_to_python_from_thread_multiple_sequential(): 6814299Sbbruce@ucdavis.edu """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially. 6914299Sbbruce@ucdavis.edu 7014299Sbbruce@ucdavis.edu It runs in a separate process to be able to stop and assert if it deadlocks. 7114299Sbbruce@ucdavis.edu """ 7214299Sbbruce@ucdavis.edu assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0 7314299Sbbruce@ucdavis.edu 7414299Sbbruce@ucdavis.edu 7514299Sbbruce@ucdavis.edudef test_python_to_cpp_to_python_from_process(): 7614299Sbbruce@ucdavis.edu """Makes sure there is no GIL deadlock when using processes. 7714299Sbbruce@ucdavis.edu 7814299Sbbruce@ucdavis.edu This test is for completion, but it was never an issue. 7914299Sbbruce@ucdavis.edu """ 8014299Sbbruce@ucdavis.edu assert _run_in_process(_python_to_cpp_to_python) == 0 8114299Sbbruce@ucdavis.edu 8214299Sbbruce@ucdavis.edu 8314299Sbbruce@ucdavis.edudef test_cross_module_gil(): 8414299Sbbruce@ucdavis.edu """Makes sure that the GIL can be acquired by another module from a GIL-released state.""" 8514299Sbbruce@ucdavis.edu m.test_cross_module_gil() # Should not raise a SIGSEGV 86