|
|
|||
File indexing completed on 2026-09-14 09:17:40
0001 // Copyright (c) 2023 The pybind Community. 0002 0003 #pragma once 0004 0005 #include "detail/common.h" 0006 #include "detail/internals.h" 0007 #include "gil.h" 0008 0009 #include <cassert> 0010 #include <mutex> 0011 0012 #if defined(Py_GIL_DISABLED) || defined(PYBIND11_HAS_SUBINTERPRETER_SUPPORT) 0013 # include <atomic> 0014 #endif 0015 #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT 0016 # include <cstdint> 0017 # include <memory> 0018 # include <string> 0019 #endif 0020 0021 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 0022 0023 PYBIND11_NAMESPACE_BEGIN(detail) 0024 #if defined(Py_GIL_DISABLED) || defined(PYBIND11_HAS_SUBINTERPRETER_SUPPORT) 0025 using atomic_bool = std::atomic_bool; 0026 #else 0027 using atomic_bool = bool; 0028 #endif 0029 PYBIND11_NAMESPACE_END(detail) 0030 0031 // Use the `gil_safe_call_once_and_store` class below instead of the naive 0032 // 0033 // static auto imported_obj = py::module_::import("module_name"); // BAD, DO NOT USE! 0034 // 0035 // which has two serious issues: 0036 // 0037 // 1. Py_DECREF() calls potentially after the Python interpreter was finalized already, and 0038 // 2. deadlocks in multi-threaded processes (because of missing lock ordering). 0039 // 0040 // The following alternative avoids both problems: 0041 // 0042 // PYBIND11_CONSTINIT static py::gil_safe_call_once_and_store<py::object> storage; 0043 // auto &imported_obj = storage // Do NOT make this `static`! 0044 // .call_once_and_store_result([]() { 0045 // return py::module_::import("module_name"); 0046 // }) 0047 // .get_stored(); 0048 // 0049 // The parameter of `call_once_and_store_result()` must be callable. It can make 0050 // CPython API calls, and in particular, it can temporarily release the GIL. 0051 // 0052 // `T` can be any C++ type, it does not have to involve CPython API types. 0053 // 0054 // The behavior with regard to signals, e.g. `SIGINT` (`KeyboardInterrupt`), 0055 // is not ideal. If the main thread is the one to actually run the `Callable`, 0056 // then a `KeyboardInterrupt` will interrupt it if it is running normal Python 0057 // code. The situation is different if a non-main thread runs the 0058 // `Callable`, and then the main thread starts waiting for it to complete: 0059 // a `KeyboardInterrupt` will not interrupt the non-main thread, but it will 0060 // get processed only when it is the main thread's turn again and it is running 0061 // normal Python code. However, this will be unnoticeable for quick call-once 0062 // functions, which is usually the case. 0063 // 0064 // For in-depth background, see docs/advanced/deadlock.md 0065 #ifndef PYBIND11_HAS_SUBINTERPRETER_SUPPORT 0066 // Subinterpreter support is disabled. 0067 // In this case, we can store the result globally, because there is only a single interpreter. 0068 // 0069 // The life span of the stored result is the entire process lifetime. It is leaked on process 0070 // termination to avoid destructor calls after the Python interpreter was finalized. 0071 template <typename T> 0072 class gil_safe_call_once_and_store { 0073 public: 0074 // PRECONDITION: The GIL must be held when `call_once_and_store_result()` is called. 0075 // 0076 // NOTE: The second parameter (finalize callback) is intentionally unused when subinterpreter 0077 // support is disabled. In that case, storage is process-global and intentionally leaked to 0078 // avoid calling destructors after the Python interpreter has been finalized. 0079 template <typename Callable> 0080 gil_safe_call_once_and_store &call_once_and_store_result(Callable &&fn, 0081 void (*)(T &) /*unused*/ = nullptr) { 0082 if (!is_initialized_) { // This read is guarded by the GIL. 0083 // Multiple threads may enter here, because the GIL is released in the next line and 0084 // CPython API calls in the `fn()` call below may release and reacquire the GIL. 0085 gil_scoped_release gil_rel; // Needed to establish lock ordering. 0086 std::call_once(once_flag_, [&] { 0087 // Only one thread will ever enter here. 0088 gil_scoped_acquire gil_acq; 0089 ::new (storage_) T(fn()); // fn may release, but will reacquire, the GIL. 0090 is_initialized_ = true; // This write is guarded by the GIL. 0091 }); 0092 // All threads will observe `is_initialized_` as true here. 0093 } 0094 // Intentionally not returning `T &` to ensure the calling code is self-documenting. 0095 return *this; 0096 } 0097 0098 // This must only be called after `call_once_and_store_result()` was called. 0099 T &get_stored() { 0100 assert(is_initialized_); 0101 PYBIND11_WARNING_PUSH 0102 # if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 5 0103 // Needed for gcc 4.8.5 0104 PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing") 0105 # endif 0106 return *reinterpret_cast<T *>(storage_); 0107 PYBIND11_WARNING_POP 0108 } 0109 0110 constexpr gil_safe_call_once_and_store() = default; 0111 // The instance is a global static, so its destructor runs when the process 0112 // is terminating. Therefore, do nothing here because the Python interpreter 0113 // may have been finalized already. 0114 PYBIND11_DTOR_CONSTEXPR ~gil_safe_call_once_and_store() = default; 0115 0116 // Disable copy and move operations. 0117 gil_safe_call_once_and_store(const gil_safe_call_once_and_store &) = delete; 0118 gil_safe_call_once_and_store(gil_safe_call_once_and_store &&) = delete; 0119 gil_safe_call_once_and_store &operator=(const gil_safe_call_once_and_store &) = delete; 0120 gil_safe_call_once_and_store &operator=(gil_safe_call_once_and_store &&) = delete; 0121 0122 private: 0123 // The global static storage (per-process) when subinterpreter support is disabled. 0124 alignas(T) char storage_[sizeof(T)] = {}; 0125 std::once_flag once_flag_; 0126 0127 // The `is_initialized_`-`storage_` pair is very similar to `std::optional`, 0128 // but the latter does not have the triviality properties of former, 0129 // therefore `std::optional` is not a viable alternative here. 0130 detail::atomic_bool is_initialized_{false}; 0131 }; 0132 #else 0133 // Subinterpreter support is enabled. 0134 // In this case, we should store the result per-interpreter instead of globally, because each 0135 // subinterpreter has its own separate state. The cached result may not shareable across 0136 // interpreters (e.g., imported modules and their members). 0137 0138 PYBIND11_NAMESPACE_BEGIN(detail) 0139 0140 template <typename T> 0141 struct call_once_storage { 0142 alignas(T) char storage[sizeof(T)] = {}; 0143 std::once_flag once_flag; 0144 void (*finalize)(T &) = nullptr; 0145 std::atomic_bool is_initialized{false}; 0146 0147 call_once_storage() = default; 0148 ~call_once_storage() { 0149 if (is_initialized) { 0150 if (finalize != nullptr) { 0151 finalize(*reinterpret_cast<T *>(storage)); 0152 } else { 0153 reinterpret_cast<T *>(storage)->~T(); 0154 } 0155 } 0156 } 0157 call_once_storage(const call_once_storage &) = delete; 0158 call_once_storage(call_once_storage &&) = delete; 0159 call_once_storage &operator=(const call_once_storage &) = delete; 0160 call_once_storage &operator=(call_once_storage &&) = delete; 0161 }; 0162 0163 PYBIND11_NAMESPACE_END(detail) 0164 0165 // Prefix for storage keys in the interpreter state dict. 0166 # define PYBIND11_CALL_ONCE_STORAGE_KEY_PREFIX PYBIND11_INTERNALS_ID "_call_once_storage__" 0167 0168 // The life span of the stored result is the entire interpreter lifetime. An additional 0169 // `finalize_fn` can be provided to clean up the stored result when the interpreter is destroyed. 0170 template <typename T> 0171 class gil_safe_call_once_and_store { 0172 public: 0173 // PRECONDITION: The GIL must be held when `call_once_and_store_result()` is called. 0174 template <typename Callable> 0175 gil_safe_call_once_and_store &call_once_and_store_result(Callable &&fn, 0176 void (*finalize_fn)(T &) = nullptr) { 0177 if (!is_last_storage_valid()) { 0178 // Multiple threads may enter here, because the GIL is released in the next line and 0179 // CPython API calls in the `fn()` call below may release and reacquire the GIL. 0180 gil_scoped_release gil_rel; // Needed to establish lock ordering. 0181 // There can be multiple threads going through here. 0182 storage_type *value = nullptr; 0183 { 0184 gil_scoped_acquire gil_acq; // Restore lock ordering. 0185 // This function is thread-safe under free-threading. 0186 value = get_or_create_storage_in_state_dict(); 0187 } 0188 assert(value != nullptr); 0189 std::call_once(value->once_flag, [&] { 0190 // Only one thread will ever enter here. 0191 gil_scoped_acquire gil_acq; 0192 // fn may release, but will reacquire, the GIL. 0193 ::new (value->storage) T(fn()); 0194 value->finalize = finalize_fn; 0195 value->is_initialized = true; 0196 last_storage_ptr_ = reinterpret_cast<T *>(value->storage); 0197 is_initialized_by_at_least_one_interpreter_ = true; 0198 }); 0199 // All threads will observe `is_initialized_by_at_least_one_interpreter_` as true here. 0200 } 0201 // Intentionally not returning `T &` to ensure the calling code is self-documenting. 0202 return *this; 0203 } 0204 0205 // This must only be called after `call_once_and_store_result()` was called. 0206 T &get_stored() { 0207 T *result = last_storage_ptr_; 0208 if (!is_last_storage_valid()) { 0209 gil_scoped_acquire gil_acq; 0210 auto *value = get_or_create_storage_in_state_dict(); 0211 result = last_storage_ptr_ = reinterpret_cast<T *>(value->storage); 0212 } 0213 assert(result != nullptr); 0214 return *result; 0215 } 0216 0217 constexpr gil_safe_call_once_and_store() = default; 0218 // The instance is a global static, so its destructor runs when the process 0219 // is terminating. Therefore, do nothing here because the Python interpreter 0220 // may have been finalized already. 0221 PYBIND11_DTOR_CONSTEXPR ~gil_safe_call_once_and_store() = default; 0222 0223 // Disable copy and move operations because the memory address is used as key. 0224 gil_safe_call_once_and_store(const gil_safe_call_once_and_store &) = delete; 0225 gil_safe_call_once_and_store(gil_safe_call_once_and_store &&) = delete; 0226 gil_safe_call_once_and_store &operator=(const gil_safe_call_once_and_store &) = delete; 0227 gil_safe_call_once_and_store &operator=(gil_safe_call_once_and_store &&) = delete; 0228 0229 private: 0230 using storage_type = detail::call_once_storage<T>; 0231 0232 // Indicator of fast path for single-interpreter case. 0233 bool is_last_storage_valid() const { 0234 return is_initialized_by_at_least_one_interpreter_ 0235 && !detail::has_seen_non_main_interpreter(); 0236 } 0237 0238 // Get the unique key for this storage instance in the interpreter's state dict. 0239 // The return type should not be `py::str` because PyObject is interpreter-dependent. 0240 std::string get_storage_key() const { 0241 // The instance is expected to be global static, so using its address as unique identifier. 0242 // The typical usage is like: 0243 // 0244 // PYBIND11_CONSTINIT static gil_safe_call_once_and_store<T> storage; 0245 // 0246 return PYBIND11_CALL_ONCE_STORAGE_KEY_PREFIX 0247 + std::to_string(reinterpret_cast<std::uintptr_t>(this)); 0248 } 0249 0250 // Get or create per-storage capsule in the current interpreter's state dict. 0251 // The storage is interpreter-dependent and will not be shared across interpreters. 0252 storage_type *get_or_create_storage_in_state_dict() { 0253 return detail::atomic_get_or_create_in_state_dict<storage_type>(get_storage_key().c_str()) 0254 .first; 0255 } 0256 0257 // No storage needed when subinterpreter support is enabled. 0258 // The actual storage is stored in the per-interpreter state dict via 0259 // `get_or_create_storage_in_state_dict()`. 0260 0261 // Fast local cache to avoid repeated lookups when there are no multiple interpreters. 0262 // This is only valid if there is a single interpreter. Otherwise, it is not used. 0263 // WARNING: We cannot use thread local cache similar to `internals_pp_manager::internals_p_tls` 0264 // because the thread local storage cannot be explicitly invalidated when interpreters 0265 // are destroyed (unlike `internals_pp_manager` which has explicit hooks for that). 0266 T *last_storage_ptr_ = nullptr; 0267 // This flag is true if the value has been initialized by any interpreter (may not be the 0268 // current one). 0269 detail::atomic_bool is_initialized_by_at_least_one_interpreter_{false}; 0270 }; 0271 #endif 0272 0273 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|