Skip to content

Commit 49ed882

Browse files
committed
[skip ci] Traverse all DSOs to find memory::guarded_delete with matching RTTI.
1 parent 6087734 commit 49ed882

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

include/pybind11/detail/internals.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,7 @@ struct internals {
255255

256256
type_map<PyObject *> native_enum_type_map;
257257

258-
// Note: get_internals().get_memory_guarded_delete does
259-
// not need to be wrapped in with_internals().
260-
memory::get_guarded_delete_fn get_memory_guarded_delete = memory::get_guarded_delete;
258+
std::vector<memory::get_guarded_delete_fn> memory_guarded_delete_fns; // See PRs #5728, #5700.
261259

262260
internals()
263261
: static_property_type(make_static_property_type()),
@@ -267,6 +265,7 @@ struct internals {
267265

268266
istate = cur_tstate->interp;
269267
registered_exception_translators.push_front(&translate_exception);
268+
memory_guarded_delete_fns.push_back(memory::get_guarded_delete);
270269
#ifdef Py_GIL_DISABLED
271270
// Scale proportional to the number of cores. 2x is a heuristic to reduce contention.
272271
auto num_shards
@@ -676,6 +675,19 @@ inline auto with_exception_translators(const F &cb)
676675
local_internals.registered_exception_translators);
677676
}
678677

678+
// Traverse all DSOs to find memory::guarded_delete with matching RTTI.
679+
inline memory::guarded_delete *find_memory_guarded_delete(const std::shared_ptr<void> &ptr) {
680+
return with_internals([&](detail::internals &internals) -> memory::guarded_delete * {
681+
for (auto fn : internals.memory_guarded_delete_fns) {
682+
memory::guarded_delete *gd = fn(ptr);
683+
if (gd) {
684+
return gd;
685+
}
686+
}
687+
return nullptr;
688+
});
689+
}
690+
679691
inline std::uint64_t mix64(std::uint64_t z) {
680692
// David Stafford's variant 13 of the MurmurHash3 finalizer popularized
681693
// by the SplitMix PRNG.

include/pybind11/detail/type_caster_base.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ struct value_and_holder_helper {
532532

533533
// have_holder() must be true or this function will fail.
534534
void throw_if_instance_is_currently_owned_by_shared_ptr() const {
535-
auto *vptr_gd_ptr = get_internals().get_memory_guarded_delete(holder().vptr);
535+
auto *vptr_gd_ptr = find_memory_guarded_delete(holder().vptr);
536536
if (vptr_gd_ptr != nullptr && !vptr_gd_ptr->released_ptr.expired()) {
537537
throw value_error("Python instance is currently owned by a std::shared_ptr.");
538538
}
@@ -576,7 +576,7 @@ handle smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&src,
576576
}
577577
// Critical transfer-of-ownership section. This must stay together.
578578
self_life_support->deactivate_life_support();
579-
holder.reclaim_disowned(get_internals().get_memory_guarded_delete);
579+
holder.reclaim_disowned(find_memory_guarded_delete);
580580
(void) src.release();
581581
// Critical section end.
582582
return existing_inst;
@@ -763,7 +763,7 @@ struct load_helper : value_and_holder_helper {
763763
}
764764
auto *type_raw_ptr = static_cast<T *>(void_raw_ptr);
765765
if (python_instance_is_alias && !force_potentially_slicing_shared_ptr) {
766-
auto *vptr_gd_ptr = get_internals().get_memory_guarded_delete(holder().vptr);
766+
auto *vptr_gd_ptr = find_memory_guarded_delete(holder().vptr);
767767
if (vptr_gd_ptr != nullptr) {
768768
std::shared_ptr<void> released_ptr = vptr_gd_ptr->released_ptr.lock();
769769
if (released_ptr) {
@@ -818,14 +818,14 @@ struct load_helper : value_and_holder_helper {
818818
// This is enforced indirectly by a static_assert in the class_ implementation:
819819
assert(!python_instance_is_alias || self_life_support);
820820

821-
std::unique_ptr<D> extracted_deleter = holder().template extract_deleter<T, D>(
822-
context, get_internals().get_memory_guarded_delete);
821+
std::unique_ptr<D> extracted_deleter
822+
= holder().template extract_deleter<T, D>(context, find_memory_guarded_delete);
823823

824824
// Critical transfer-of-ownership section. This must stay together.
825825
if (self_life_support != nullptr) {
826-
holder().disown(get_internals().get_memory_guarded_delete);
826+
holder().disown(find_memory_guarded_delete);
827827
} else {
828-
holder().release_ownership(get_internals().get_memory_guarded_delete);
828+
holder().release_ownership(find_memory_guarded_delete);
829829
}
830830
auto result = unique_with_deleter<T, D>(raw_type_ptr, std::move(extracted_deleter));
831831
if (self_life_support != nullptr) {
@@ -851,7 +851,7 @@ struct load_helper : value_and_holder_helper {
851851
holder().template ensure_compatible_rtti_uqp_del<T, D>(context);
852852
return unique_with_deleter<T, D>(raw_type_ptr,
853853
std::move(holder().template extract_deleter<T, D>(
854-
context, get_internals().get_memory_guarded_delete)));
854+
context, find_memory_guarded_delete)));
855855
}
856856
};
857857

0 commit comments

Comments
 (0)