mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-21 20:55:11 +00:00
baa540ec34
* Support free-threaded CPython (PEP 703) Some additional locking is added in the free-threaded build when `Py_GIL_DISABLED` is defined: - Most accesses to internals are protected by a single mutex - The registered_instances uses a striped lock to improve concurrency Pybind11 modules can indicate support for running with the GIL disabled by calling `set_gil_not_used()`. * refactor: use PYBIND11_MODULE (#11) Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * Address code review * Suppress MSVC warning * Changes from review * style: pre-commit fixes * `py::mod_gil_not_used()` suggestion. * Update include/pybind11/pybind11.h --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com>
55 lines
1.8 KiB
C++
55 lines
1.8 KiB
C++
/*
|
|
Copyright (c) 2022 Google LLC
|
|
|
|
All rights reserved. Use of this source code is governed by a
|
|
BSD-style license that can be found in the LICENSE file.
|
|
*/
|
|
|
|
#include <pybind11/pybind11.h>
|
|
|
|
// This file mimics a DSO that makes pybind11 calls but does not define a PYBIND11_MODULE,
|
|
// so that the first call of cross_module_error_already_set() triggers the first call of
|
|
// pybind11::detail::get_internals().
|
|
|
|
namespace {
|
|
|
|
namespace py = pybind11;
|
|
|
|
void interleaved_error_already_set() {
|
|
py::set_error(PyExc_RuntimeError, "1st error.");
|
|
try {
|
|
throw py::error_already_set();
|
|
} catch (const py::error_already_set &) {
|
|
// The 2nd error could be conditional in a real application.
|
|
py::set_error(PyExc_RuntimeError, "2nd error.");
|
|
} // Here the 1st error is destroyed before the 2nd error is fetched.
|
|
// The error_already_set dtor triggers a pybind11::detail::get_internals()
|
|
// call via pybind11::gil_scoped_acquire.
|
|
if (PyErr_Occurred()) {
|
|
throw py::error_already_set();
|
|
}
|
|
}
|
|
|
|
constexpr char kModuleName[] = "cross_module_interleaved_error_already_set";
|
|
|
|
struct PyModuleDef moduledef = {
|
|
PyModuleDef_HEAD_INIT, kModuleName, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr};
|
|
|
|
} // namespace
|
|
|
|
extern "C" PYBIND11_EXPORT PyObject *PyInit_cross_module_interleaved_error_already_set() {
|
|
PyObject *m = PyModule_Create(&moduledef);
|
|
if (m != nullptr) {
|
|
static_assert(sizeof(&interleaved_error_already_set) == sizeof(void *),
|
|
"Function pointer must have the same size as void *");
|
|
#ifdef Py_GIL_DISABLED
|
|
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
|
#endif
|
|
PyModule_AddObject(
|
|
m,
|
|
"funcaddr",
|
|
PyLong_FromVoidPtr(reinterpret_cast<void *>(&interleaved_error_already_set)));
|
|
}
|
|
return m;
|
|
}
|