Skip to content

Commit d9227ce

Browse files
committed
Move code location
1 parent 740f693 commit d9227ce

1 file changed

Lines changed: 25 additions & 24 deletions

File tree

include/pybind11/pybind11.h

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,30 +1692,6 @@ class generic_type : public object {
16921692

16931693
m_ptr = make_new_python_type(rec);
16941694

1695-
// Prevent use-after-free during interpreter shutdown. GC order is not guaranteed, so the
1696-
// internals capsule may be destroyed (resetting internals via internals_shutdown) before
1697-
// all pybind11 types are destroyed. If a type's tp_traverse/tp_clear then calls py::cast,
1698-
// it would recreate an empty internals and fail because the type registry is gone. By
1699-
// holding references to the capsules, we ensure they outlive all pybind11 types.
1700-
// We use weakrefs on the type with a cpp_function callback. When the type is destroyed,
1701-
// Python will call the callback which releases the capsule reference and the weakref.
1702-
if (PyObject *capsule = get_internals_capsule()) {
1703-
Py_INCREF(capsule);
1704-
(void) weakref(handle(m_ptr), cpp_function([](handle prevent_release) -> void {
1705-
Py_XDECREF(get_internals_capsule());
1706-
prevent_release.dec_ref();
1707-
}))
1708-
.release();
1709-
}
1710-
if (PyObject *capsule = get_local_internals_capsule()) {
1711-
Py_INCREF(capsule);
1712-
(void) weakref(handle(m_ptr), cpp_function([](handle prevent_release) -> void {
1713-
Py_XDECREF(get_local_internals_capsule());
1714-
prevent_release.dec_ref();
1715-
}))
1716-
.release();
1717-
}
1718-
17191695
/* Register supplemental type information in C++ dict */
17201696
auto *tinfo = new detail::type_info();
17211697
tinfo->type = reinterpret_cast<PyTypeObject *>(m_ptr);
@@ -1745,6 +1721,31 @@ class generic_type : public object {
17451721
#endif
17461722
}
17471723

1724+
// Prevent use-after-free during interpreter shutdown. GC order is not guaranteed, so
1725+
// the internals capsule may be destroyed (resetting internals via internals_shutdown)
1726+
// before all pybind11 types are destroyed. If a type's tp_traverse/tp_clear then calls
1727+
// py::cast, it would recreate an empty internals and fail because the type registry is
1728+
// gone. By holding references to the capsules, we ensure they outlive all pybind11
1729+
// types. We use weakrefs on the type with a cpp_function callback. When the type is
1730+
// destroyed, Python will call the callback which releases the capsule reference and
1731+
// the weakref.
1732+
if (PyObject *capsule = get_internals_capsule()) {
1733+
Py_INCREF(capsule);
1734+
(void) weakref(handle(m_ptr), cpp_function([](handle prevent_release) -> void {
1735+
Py_XDECREF(get_internals_capsule());
1736+
prevent_release.dec_ref();
1737+
}))
1738+
.release();
1739+
}
1740+
if (PyObject *capsule = get_local_internals_capsule()) {
1741+
Py_INCREF(capsule);
1742+
(void) weakref(handle(m_ptr), cpp_function([](handle prevent_release) -> void {
1743+
Py_XDECREF(get_local_internals_capsule());
1744+
prevent_release.dec_ref();
1745+
}))
1746+
.release();
1747+
}
1748+
17481749
PYBIND11_WARNING_PUSH
17491750
#if defined(__GNUC__) && __GNUC__ == 12
17501751
// When using GCC 12 these warnings are disabled as they trigger

0 commit comments

Comments
 (0)