Skip to content

Commit 59ef530

Browse files
authored
[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.
1 parent 4e1e2fe commit 59ef530

File tree

3 files changed

+9
-2
lines changed

3 files changed

+9
-2
lines changed

include/pybind11/detail/smart_holder_type_casters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ struct shared_ptr_trampoline_self_life_support {
400400
PyObject *self;
401401
explicit shared_ptr_trampoline_self_life_support(instance *inst)
402402
: self{reinterpret_cast<PyObject *>(inst)} {
403+
gil_scoped_acquire gil;
403404
Py_INCREF(self);
404405
}
405406
void operator()(void *) {

tests/test_class_sh_trampoline_shared_ptr_cpp_arg.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ TEST_SUBMODULE(class_sh_trampoline_shared_ptr_cpp_arg, m) {
6969
.def("has_python_instance", &SpBase::has_python_instance);
7070

7171
m.def("pass_through_shd_ptr", pass_through_shd_ptr);
72+
m.def("pass_through_shd_ptr_release_gil",
73+
pass_through_shd_ptr,
74+
py::call_guard<py::gil_scoped_release>()); // PR #4196
7275

7376
py::classh<SpBaseTester>(m, "SpBaseTester")
7477
.def(py::init<>())

tests/test_class_sh_trampoline_shared_ptr_cpp_arg.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,15 @@ def test_infinite():
132132
break # Comment out for manual leak checking (use `top` command).
133133

134134

135-
def test_std_make_shared_factory():
135+
@pytest.mark.parametrize(
136+
"pass_through_func", [m.pass_through_shd_ptr, m.pass_through_shd_ptr_release_gil]
137+
)
138+
def test_std_make_shared_factory(pass_through_func):
136139
class PyChild(m.SpBase):
137140
def __init__(self):
138141
super().__init__(0)
139142

140143
obj = PyChild()
141144
while True:
142-
assert m.pass_through_shd_ptr(obj) is obj
145+
assert pass_through_func(obj) is obj
143146
break # Comment out for manual leak checking (use `top` command).

0 commit comments

Comments
 (0)