[smart_holder] Add gil_scoped_acquire to shared_ptr_trampoline_self_life_support ctor. (#4196)

* Add `gil_scoped_acquire` to `shared_ptr_trampoline_self_life_support` ctor.

* Add test exercising fix & validation that the fix is needed (i.e. this is BROKEN).

test_class_sh_trampoline_shared_ptr_cpp_arg.py::test_std_make_shared_factory[pass_through_shd_ptr] PASSED                            [ 87%]
test_class_sh_trampoline_shared_ptr_cpp_arg.py::test_std_make_shared_factory[pass_through_shd_ptr_release_gil] FAILED                [100%]

```
================================================================= FAILURES =================================================================
______________________________________ test_std_make_shared_factory[pass_through_shd_ptr_release_gil] ______________________________________

pass_through_func = <built-in method pass_through_shd_ptr_release_gil of PyCapsule object at 0x7f1b209707b0>

    @pytest.mark.parametrize(
        "pass_through_func", [m.pass_through_shd_ptr, m.pass_through_shd_ptr_release_gil]
    )
    def test_std_make_shared_factory(pass_through_func):
        class PyChild(m.SpBase):
            def __init__(self):
                super().__init__(0)

        obj = PyChild()
        while True:
>           assert pass_through_func(obj) is obj
E           RuntimeError: NEEDED HERE: gil_scoped_acquire gil;
```

* Put back fix.
This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-10-07 12:24:49 -07:00 committed by GitHub
parent 4e1e2fe62a
commit 59ef5307ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 2 deletions

View File

@ -400,6 +400,7 @@ struct shared_ptr_trampoline_self_life_support {
PyObject *self; PyObject *self;
explicit shared_ptr_trampoline_self_life_support(instance *inst) explicit shared_ptr_trampoline_self_life_support(instance *inst)
: self{reinterpret_cast<PyObject *>(inst)} { : self{reinterpret_cast<PyObject *>(inst)} {
gil_scoped_acquire gil;
Py_INCREF(self); Py_INCREF(self);
} }
void operator()(void *) { void operator()(void *) {

View File

@ -69,6 +69,9 @@ TEST_SUBMODULE(class_sh_trampoline_shared_ptr_cpp_arg, m) {
.def("has_python_instance", &SpBase::has_python_instance); .def("has_python_instance", &SpBase::has_python_instance);
m.def("pass_through_shd_ptr", pass_through_shd_ptr); m.def("pass_through_shd_ptr", pass_through_shd_ptr);
m.def("pass_through_shd_ptr_release_gil",
pass_through_shd_ptr,
py::call_guard<py::gil_scoped_release>()); // PR #4196
py::classh<SpBaseTester>(m, "SpBaseTester") py::classh<SpBaseTester>(m, "SpBaseTester")
.def(py::init<>()) .def(py::init<>())

View File

@ -132,12 +132,15 @@ def test_infinite():
break # Comment out for manual leak checking (use `top` command). break # Comment out for manual leak checking (use `top` command).
def test_std_make_shared_factory(): @pytest.mark.parametrize(
"pass_through_func", [m.pass_through_shd_ptr, m.pass_through_shd_ptr_release_gil]
)
def test_std_make_shared_factory(pass_through_func):
class PyChild(m.SpBase): class PyChild(m.SpBase):
def __init__(self): def __init__(self):
super().__init__(0) super().__init__(0)
obj = PyChild() obj = PyChild()
while True: while True:
assert m.pass_through_shd_ptr(obj) is obj assert pass_through_func(obj) is obj
break # Comment out for manual leak checking (use `top` command). break # Comment out for manual leak checking (use `top` command).