Skip to content

Commit

Permalink
fix: Make gil_safe_call_once thread-safe in free-threaded CPython
Browse files Browse the repository at this point in the history
The "is_initialized_" flags is not protected by the GIL in free-threaded
Python, so it needs to be an atomic field.

Fixes #5245
  • Loading branch information
colesbury committed Jul 16, 2024
1 parent ccefee4 commit d87b0db
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/pybind11/gil_safe_call_once.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

#include <cassert>
#include <mutex>
#ifdef Py_GIL_DISABLED
#include <atomic>
#endif

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

Expand Down Expand Up @@ -82,7 +85,11 @@ class gil_safe_call_once_and_store {
private:
alignas(T) char storage_[sizeof(T)] = {};
std::once_flag once_flag_ = {};
#ifdef Py_GIL_DISABLED
std::atomic_bool is_initialized_{false};
#else
bool is_initialized_ = false;
#endif
// The `is_initialized_`-`storage_` pair is very similar to `std::optional`,
// but the latter does not have the triviality properties of former,
// therefore `std::optional` is not a viable alternative here.
Expand Down

0 comments on commit d87b0db

Please sign in to comment.