aboutsummaryrefslogtreecommitdiff
path: root/tests/test_gil_scoped.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_gil_scoped.cpp')
-rw-r--r--tests/test_gil_scoped.cpp146
1 files changed, 118 insertions, 28 deletions
diff --git a/tests/test_gil_scoped.cpp b/tests/test_gil_scoped.cpp
index b6a45a5f..f136086e 100644
--- a/tests/test_gil_scoped.cpp
+++ b/tests/test_gil_scoped.cpp
@@ -7,48 +7,138 @@
BSD-style license that can be found in the LICENSE file.
*/
-#include "pybind11_tests.h"
#include <pybind11/functional.h>
+#include "pybind11_tests.h"
+
+#include <string>
+#include <thread>
+
+#define CROSS_MODULE(Function) \
+ auto cm = py::module_::import("cross_module_gil_utils"); \
+ auto target = reinterpret_cast<void (*)()>(PyLong_AsVoidPtr(cm.attr(Function).ptr()));
-class VirtClass {
+class VirtClass {
public:
virtual ~VirtClass() = default;
VirtClass() = default;
- VirtClass(const VirtClass&) = delete;
+ VirtClass(const VirtClass &) = delete;
virtual void virtual_func() {}
virtual void pure_virtual_func() = 0;
};
class PyVirtClass : public VirtClass {
- void virtual_func() override {
- PYBIND11_OVERRIDE(void, VirtClass, virtual_func,);
- }
+ void virtual_func() override { PYBIND11_OVERRIDE(void, VirtClass, virtual_func, ); }
void pure_virtual_func() override {
- PYBIND11_OVERRIDE_PURE(void, VirtClass, pure_virtual_func,);
+ PYBIND11_OVERRIDE_PURE(void, VirtClass, pure_virtual_func, );
}
};
TEST_SUBMODULE(gil_scoped, m) {
- py::class_<VirtClass, PyVirtClass>(m, "VirtClass")
- .def(py::init<>())
- .def("virtual_func", &VirtClass::virtual_func)
- .def("pure_virtual_func", &VirtClass::pure_virtual_func);
-
- m.def("test_callback_py_obj",
- [](py::object func) { func(); });
- m.def("test_callback_std_func",
- [](const std::function<void()> &func) { func(); });
- m.def("test_callback_virtual_func",
- [](VirtClass &virt) { virt.virtual_func(); });
- m.def("test_callback_pure_virtual_func",
- [](VirtClass &virt) { virt.pure_virtual_func(); });
- m.def("test_cross_module_gil",
- []() {
- auto cm = py::module_::import("cross_module_gil_utils");
- auto gil_acquire = reinterpret_cast<void (*)()>(
- PyLong_AsVoidPtr(cm.attr("gil_acquire_funcaddr").ptr()));
- py::gil_scoped_release gil_release;
- gil_acquire();
- });
+ m.attr("defined_THREAD_SANITIZER") =
+#if defined(THREAD_SANITIZER)
+ true;
+#else
+ false;
+#endif
+
+ m.def("intentional_deadlock",
+ []() { std::thread([]() { py::gil_scoped_acquire gil_acquired; }).join(); });
+
+ py::class_<VirtClass, PyVirtClass>(m, "VirtClass")
+ .def(py::init<>())
+ .def("virtual_func", &VirtClass::virtual_func)
+ .def("pure_virtual_func", &VirtClass::pure_virtual_func);
+
+ m.def("test_callback_py_obj", [](py::object &func) { func(); });
+ m.def("test_callback_std_func", [](const std::function<void()> &func) { func(); });
+ m.def("test_callback_virtual_func", [](VirtClass &virt) { virt.virtual_func(); });
+ m.def("test_callback_pure_virtual_func", [](VirtClass &virt) { virt.pure_virtual_func(); });
+ m.def("test_cross_module_gil_released", []() {
+ CROSS_MODULE("gil_acquire_funcaddr")
+ py::gil_scoped_release gil_release;
+ target();
+ });
+ m.def("test_cross_module_gil_acquired", []() {
+ CROSS_MODULE("gil_acquire_funcaddr")
+ py::gil_scoped_acquire gil_acquire;
+ target();
+ });
+ m.def("test_cross_module_gil_inner_custom_released", []() {
+ CROSS_MODULE("gil_acquire_inner_custom_funcaddr")
+ py::gil_scoped_release gil_release;
+ target();
+ });
+ m.def("test_cross_module_gil_inner_custom_acquired", []() {
+ CROSS_MODULE("gil_acquire_inner_custom_funcaddr")
+ py::gil_scoped_acquire gil_acquire;
+ target();
+ });
+ m.def("test_cross_module_gil_inner_pybind11_released", []() {
+ CROSS_MODULE("gil_acquire_inner_pybind11_funcaddr")
+ py::gil_scoped_release gil_release;
+ target();
+ });
+ m.def("test_cross_module_gil_inner_pybind11_acquired", []() {
+ CROSS_MODULE("gil_acquire_inner_pybind11_funcaddr")
+ py::gil_scoped_acquire gil_acquire;
+ target();
+ });
+ m.def("test_cross_module_gil_nested_custom_released", []() {
+ CROSS_MODULE("gil_acquire_nested_custom_funcaddr")
+ py::gil_scoped_release gil_release;
+ target();
+ });
+ m.def("test_cross_module_gil_nested_custom_acquired", []() {
+ CROSS_MODULE("gil_acquire_nested_custom_funcaddr")
+ py::gil_scoped_acquire gil_acquire;
+ target();
+ });
+ m.def("test_cross_module_gil_nested_pybind11_released", []() {
+ CROSS_MODULE("gil_acquire_nested_pybind11_funcaddr")
+ py::gil_scoped_release gil_release;
+ target();
+ });
+ m.def("test_cross_module_gil_nested_pybind11_acquired", []() {
+ CROSS_MODULE("gil_acquire_nested_pybind11_funcaddr")
+ py::gil_scoped_acquire gil_acquire;
+ target();
+ });
+ m.def("test_release_acquire", [](const py::object &obj) {
+ py::gil_scoped_release gil_released;
+ py::gil_scoped_acquire gil_acquired;
+ return py::str(obj);
+ });
+ m.def("test_nested_acquire", [](const py::object &obj) {
+ py::gil_scoped_release gil_released;
+ py::gil_scoped_acquire gil_acquired_outer;
+ py::gil_scoped_acquire gil_acquired_inner;
+ return py::str(obj);
+ });
+ m.def("test_multi_acquire_release_cross_module", [](unsigned bits) {
+ py::set internals_ids;
+ internals_ids.add(PYBIND11_INTERNALS_ID);
+ {
+ py::gil_scoped_release gil_released;
+ auto thread_f = [bits, &internals_ids]() {
+ py::gil_scoped_acquire gil_acquired;
+ auto cm = py::module_::import("cross_module_gil_utils");
+ auto target = reinterpret_cast<std::string (*)(unsigned)>(
+ PyLong_AsVoidPtr(cm.attr("gil_multi_acquire_release_funcaddr").ptr()));
+ std::string cm_internals_id = target(bits >> 3);
+ internals_ids.add(cm_internals_id);
+ };
+ if ((bits & 0x1u) != 0u) {
+ thread_f();
+ }
+ if ((bits & 0x2u) != 0u) {
+ std::thread non_python_thread(thread_f);
+ non_python_thread.join();
+ }
+ if ((bits & 0x4u) != 0u) {
+ thread_f();
+ }
+ }
+ return internals_ids;
+ });
}