File indexing completed on 2025-01-18 10:17:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <pybind11/functional.h>
0011
0012 #include "pybind11_tests.h"
0013
0014 #include <string>
0015 #include <thread>
0016
0017 #define CROSS_MODULE(Function) \
0018 auto cm = py::module_::import("cross_module_gil_utils"); \
0019 auto target = reinterpret_cast<void (*)()>(PyLong_AsVoidPtr(cm.attr(Function).ptr()));
0020
0021 class VirtClass {
0022 public:
0023 virtual ~VirtClass() = default;
0024 VirtClass() = default;
0025 VirtClass(const VirtClass &) = delete;
0026 virtual void virtual_func() {}
0027 virtual void pure_virtual_func() = 0;
0028 };
0029
0030 class PyVirtClass : public VirtClass {
0031 void virtual_func() override { PYBIND11_OVERRIDE(void, VirtClass, virtual_func, ); }
0032 void pure_virtual_func() override {
0033 PYBIND11_OVERRIDE_PURE(void, VirtClass, pure_virtual_func, );
0034 }
0035 };
0036
0037 TEST_SUBMODULE(gil_scoped, m) {
0038 m.attr("defined_THREAD_SANITIZER") =
0039 #if defined(THREAD_SANITIZER)
0040 true;
0041 #else
0042 false;
0043 #endif
0044
0045 m.def("intentional_deadlock",
0046 []() { std::thread([]() { py::gil_scoped_acquire gil_acquired; }).join(); });
0047
0048 py::class_<VirtClass, PyVirtClass>(m, "VirtClass")
0049 .def(py::init<>())
0050 .def("virtual_func", &VirtClass::virtual_func)
0051 .def("pure_virtual_func", &VirtClass::pure_virtual_func);
0052
0053 m.def("test_callback_py_obj", [](py::object &func) { func(); });
0054 m.def("test_callback_std_func", [](const std::function<void()> &func) { func(); });
0055 m.def("test_callback_virtual_func", [](VirtClass &virt) { virt.virtual_func(); });
0056 m.def("test_callback_pure_virtual_func", [](VirtClass &virt) { virt.pure_virtual_func(); });
0057 m.def("test_cross_module_gil_released", []() {
0058 CROSS_MODULE("gil_acquire_funcaddr")
0059 py::gil_scoped_release gil_release;
0060 target();
0061 });
0062 m.def("test_cross_module_gil_acquired", []() {
0063 CROSS_MODULE("gil_acquire_funcaddr")
0064 py::gil_scoped_acquire gil_acquire;
0065 target();
0066 });
0067 m.def("test_cross_module_gil_inner_custom_released", []() {
0068 CROSS_MODULE("gil_acquire_inner_custom_funcaddr")
0069 py::gil_scoped_release gil_release;
0070 target();
0071 });
0072 m.def("test_cross_module_gil_inner_custom_acquired", []() {
0073 CROSS_MODULE("gil_acquire_inner_custom_funcaddr")
0074 py::gil_scoped_acquire gil_acquire;
0075 target();
0076 });
0077 m.def("test_cross_module_gil_inner_pybind11_released", []() {
0078 CROSS_MODULE("gil_acquire_inner_pybind11_funcaddr")
0079 py::gil_scoped_release gil_release;
0080 target();
0081 });
0082 m.def("test_cross_module_gil_inner_pybind11_acquired", []() {
0083 CROSS_MODULE("gil_acquire_inner_pybind11_funcaddr")
0084 py::gil_scoped_acquire gil_acquire;
0085 target();
0086 });
0087 m.def("test_cross_module_gil_nested_custom_released", []() {
0088 CROSS_MODULE("gil_acquire_nested_custom_funcaddr")
0089 py::gil_scoped_release gil_release;
0090 target();
0091 });
0092 m.def("test_cross_module_gil_nested_custom_acquired", []() {
0093 CROSS_MODULE("gil_acquire_nested_custom_funcaddr")
0094 py::gil_scoped_acquire gil_acquire;
0095 target();
0096 });
0097 m.def("test_cross_module_gil_nested_pybind11_released", []() {
0098 CROSS_MODULE("gil_acquire_nested_pybind11_funcaddr")
0099 py::gil_scoped_release gil_release;
0100 target();
0101 });
0102 m.def("test_cross_module_gil_nested_pybind11_acquired", []() {
0103 CROSS_MODULE("gil_acquire_nested_pybind11_funcaddr")
0104 py::gil_scoped_acquire gil_acquire;
0105 target();
0106 });
0107 m.def("test_release_acquire", [](const py::object &obj) {
0108 py::gil_scoped_release gil_released;
0109 py::gil_scoped_acquire gil_acquired;
0110 return py::str(obj);
0111 });
0112 m.def("test_nested_acquire", [](const py::object &obj) {
0113 py::gil_scoped_release gil_released;
0114 py::gil_scoped_acquire gil_acquired_outer;
0115 py::gil_scoped_acquire gil_acquired_inner;
0116 return py::str(obj);
0117 });
0118 m.def("test_multi_acquire_release_cross_module", [](unsigned bits) {
0119 py::set internals_ids;
0120 internals_ids.add(PYBIND11_INTERNALS_ID);
0121 {
0122 py::gil_scoped_release gil_released;
0123 auto thread_f = [bits, &internals_ids]() {
0124 py::gil_scoped_acquire gil_acquired;
0125 auto cm = py::module_::import("cross_module_gil_utils");
0126 auto target = reinterpret_cast<std::string (*)(unsigned)>(
0127 PyLong_AsVoidPtr(cm.attr("gil_multi_acquire_release_funcaddr").ptr()));
0128 std::string cm_internals_id = target(bits >> 3);
0129 internals_ids.add(cm_internals_id);
0130 };
0131 if ((bits & 0x1u) != 0u) {
0132 thread_f();
0133 }
0134 if ((bits & 0x2u) != 0u) {
0135 std::thread non_python_thread(thread_f);
0136 non_python_thread.join();
0137 }
0138 if ((bits & 0x4u) != 0u) {
0139 thread_f();
0140 }
0141 }
0142 return internals_ids;
0143 });
0144 }