Skip to content

Commit be97110

Browse files
committed
Try fix thread-safety
1 parent 2a4b118 commit be97110

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

include/pybind11/gil_safe_call_once.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ class gil_safe_call_once_and_store {
130130
// CPython API calls in the `fn()` call below may release and reacquire the GIL.
131131
gil_scoped_release gil_rel; // Needed to establish lock ordering.
132132
{
133-
gil_scoped_acquire gil_acq;
134133
detail::with_internals([&](detail::internals &internals) {
135134
// The concurrency control is done inside `detail::with_internals`.
136135
// At most one thread will enter here at a time.
@@ -141,10 +140,11 @@ class gil_safe_call_once_and_store {
141140
// already created.
142141
auto it = storage_map.find(k);
143142
if (it == storage_map.end()) {
143+
gil_scoped_acquire gil_acq;
144144
auto v = new detail::call_once_storage<T>{};
145145
::new (v->storage) T(fn()); // fn may release, but will reacquire, the GIL.
146146
v->finalize = finalize_fn;
147-
last_storage_ = reinterpret_cast<T *>(v->storage);
147+
last_storage_ptr_ = reinterpret_cast<T *>(v->storage);
148148
v->is_initialized = true;
149149
storage_map.emplace(k, v);
150150
}
@@ -159,13 +159,13 @@ class gil_safe_call_once_and_store {
159159

160160
// This must only be called after `call_once_and_store_result()` was called.
161161
T &get_stored() {
162-
T *result = last_storage_;
162+
T *result = last_storage_ptr_;
163163
if (!is_last_storage_valid()) {
164164
detail::with_internals([&](detail::internals &internals) {
165165
const void *k = reinterpret_cast<const void *>(this);
166166
auto &storage_map = internals.call_once_storage_map;
167167
auto *v = static_cast<detail::call_once_storage<T> *>(storage_map.at(k));
168-
result = last_storage_ = reinterpret_cast<T *>(v->storage);
168+
result = last_storage_ptr_ = reinterpret_cast<T *>(v->storage);
169169
});
170170
}
171171
assert(result != nullptr);
@@ -181,7 +181,7 @@ class gil_safe_call_once_and_store {
181181
private:
182182
bool is_last_storage_valid() const {
183183
return is_initialized_by_atleast_one_interpreter_
184-
&& detail::get_num_interpreters_seen() <= 1 && last_storage_ != nullptr;
184+
&& detail::get_num_interpreters_seen() <= 1;
185185
}
186186

187187
// No storage needed when subinterpreter support is enabled.
@@ -190,7 +190,7 @@ class gil_safe_call_once_and_store {
190190

191191
// Fast local cache to avoid repeated lookups when there are no multiple interpreters.
192192
// This is only valid if there is a single interpreter. Otherwise, it is not used.
193-
T *last_storage_ = nullptr;
193+
T *last_storage_ptr_ = nullptr;
194194
// This flag is true if the value has been initialized by any interpreter (may not be the
195195
// current one).
196196
atomic_bool is_initialized_by_atleast_one_interpreter_{false};

0 commit comments

Comments
 (0)