mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 22:52:01 +00:00
Bug fix: Replace bare static exception<T>
with gil_safe_call_once_and_store
. (#4897)
This is to ensure that `Py_DECREF()` is not called after the Python interpreter was finalized already:
3414c56b6c/include/pybind11/gil_safe_call_once.h (L19)
This commit is contained in:
parent
3414c56b6c
commit
bf88e29c95
@ -14,6 +14,7 @@
|
|||||||
#include "detail/init.h"
|
#include "detail/init.h"
|
||||||
#include "attr.h"
|
#include "attr.h"
|
||||||
#include "gil.h"
|
#include "gil.h"
|
||||||
|
#include "gil_safe_call_once.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "typing.h"
|
#include "typing.h"
|
||||||
|
|
||||||
@ -2609,23 +2610,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
// Returns a reference to a function-local static exception object used in the simple
|
|
||||||
// register_exception approach below. (It would be simpler to have the static local variable
|
|
||||||
// directly in register_exception, but that makes clang <3.5 segfault - issue #1349).
|
|
||||||
template <typename CppException>
|
|
||||||
exception<CppException> &get_exception_object() {
|
|
||||||
static exception<CppException> ex;
|
|
||||||
return ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function for register_exception and register_local_exception
|
// Helper function for register_exception and register_local_exception
|
||||||
template <typename CppException>
|
template <typename CppException>
|
||||||
exception<CppException> &
|
exception<CppException> &
|
||||||
register_exception_impl(handle scope, const char *name, handle base, bool isLocal) {
|
register_exception_impl(handle scope, const char *name, handle base, bool isLocal) {
|
||||||
auto &ex = detail::get_exception_object<CppException>();
|
PYBIND11_CONSTINIT static gil_safe_call_once_and_store<exception<CppException>> exc_storage;
|
||||||
if (!ex) {
|
exc_storage.call_once_and_store_result(
|
||||||
ex = exception<CppException>(scope, name, base);
|
[&]() { return exception<CppException>(scope, name, base); });
|
||||||
}
|
|
||||||
|
|
||||||
auto register_func
|
auto register_func
|
||||||
= isLocal ? ®ister_local_exception_translator : ®ister_exception_translator;
|
= isLocal ? ®ister_local_exception_translator : ®ister_exception_translator;
|
||||||
@ -2637,10 +2629,10 @@ register_exception_impl(handle scope, const char *name, handle base, bool isLoca
|
|||||||
try {
|
try {
|
||||||
std::rethrow_exception(p);
|
std::rethrow_exception(p);
|
||||||
} catch (const CppException &e) {
|
} catch (const CppException &e) {
|
||||||
set_error(detail::get_exception_object<CppException>(), e.what());
|
set_error(exc_storage.get_stored(), e.what());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return ex;
|
return exc_storage.get_stored();
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
Loading…
Reference in New Issue
Block a user