Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b5828f0

Browse files
committedMar 10, 2025··
use MutexExt instead of ThreadStateGuard
1 parent 3eab729 commit b5828f0

File tree

3 files changed

+10
-33
lines changed

3 files changed

+10
-33
lines changed
 

‎src/datetime.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,14 @@ use std::hash::Hash;
6060
use std::marker::PhantomData;
6161
use std::sync::Mutex;
6262

63+
use pyo3::sync::MutexExt;
6364
use pyo3::{Bound, Py, Python};
6465
use rustc_hash::FxHashMap;
6566

6667
use crate::dtype::{clone_methods_impl, Element, PyArrayDescr, PyArrayDescrMethods};
6768
use crate::npyffi::{
6869
PyArray_DatetimeDTypeMetaData, PyDataType_C_METADATA, NPY_DATETIMEUNIT, NPY_TYPES,
6970
};
70-
use crate::ThreadStateGuard;
7171

7272
/// Represents the [datetime units][datetime-units] supported by NumPy
7373
///
@@ -224,13 +224,10 @@ impl TypeDescriptors {
224224

225225
#[allow(clippy::wrong_self_convention)]
226226
fn from_unit<'py>(&self, py: Python<'py>, unit: NPY_DATETIMEUNIT) -> Bound<'py, PyArrayDescr> {
227-
// Detach from the runtime to avoid deadlocking on acquiring the mutex.
228-
let ts_guard = ThreadStateGuard::new();
229-
230-
let mut dtypes = self.dtypes.lock().expect("dtype cache poisoned");
231-
232-
// Now we hold the mutex so it's safe to re-attach to the runtime.
233-
drop(ts_guard);
227+
let mut dtypes = self
228+
.dtypes
229+
.lock_py_attached(py)
230+
.expect("dtype cache poisoned");
234231

235232
let dtype = match dtypes.get_or_insert_with(Default::default).entry(unit) {
236233
Entry::Occupied(entry) => entry.into_mut(),

‎src/lib.rs

-17
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,6 @@ mod doctest {
149149
#[inline(always)]
150150
fn cold() {}
151151

152-
/// An RAII guard for avoiding deadlocks with the GIL or other global
153-
/// synchronization events in the Python runtime
154-
// FIXME create a proper MutexExt trait that handles poisoning and upstream to PyO3
155-
struct ThreadStateGuard(*mut pyo3::ffi::PyThreadState);
156-
157-
impl ThreadStateGuard {
158-
fn new() -> ThreadStateGuard {
159-
ThreadStateGuard(unsafe { pyo3::ffi::PyEval_SaveThread() })
160-
}
161-
}
162-
163-
impl Drop for ThreadStateGuard {
164-
fn drop(&mut self) {
165-
unsafe { pyo3::ffi::PyEval_RestoreThread(self.0) };
166-
}
167-
}
168-
169152
/// Create a [`PyArray`] with one, two or three dimensions.
170153
///
171154
/// This macro is backed by [`ndarray::array`].

‎src/strings.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::os::raw::c_char;
1010
use std::str;
1111
use std::sync::Mutex;
1212

13+
use pyo3::sync::MutexExt;
1314
use pyo3::{
1415
ffi::{Py_UCS1, Py_UCS4},
1516
Bound, Py, Python,
@@ -19,7 +20,6 @@ use rustc_hash::FxHashMap;
1920
use crate::dtype::{clone_methods_impl, Element, PyArrayDescr, PyArrayDescrMethods};
2021
use crate::npyffi::PyDataType_SET_ELSIZE;
2122
use crate::npyffi::NPY_TYPES;
22-
use crate::ThreadStateGuard;
2323

2424
/// A newtype wrapper around [`[u8; N]`][Py_UCS1] to handle [`byte` scalars][numpy-bytes] while satisfying coherence.
2525
///
@@ -179,13 +179,10 @@ impl TypeDescriptors {
179179
byteorder: c_char,
180180
size: usize,
181181
) -> Bound<'py, PyArrayDescr> {
182-
// Detach from the runtime to avoid deadlocking on acquiring the mutex.
183-
let ts_guard = ThreadStateGuard::new();
184-
185-
let mut dtypes = self.dtypes.lock().expect("dtype cache poisoned");
186-
187-
// Now we hold the mutex so it's safe to re-attach to the runtime.
188-
drop(ts_guard);
182+
let mut dtypes = self
183+
.dtypes
184+
.lock_py_attached(py)
185+
.expect("dtype cache poisoned");
189186

190187
let dtype = match dtypes.get_or_insert_with(Default::default).entry(size) {
191188
Entry::Occupied(entry) => entry.into_mut(),

0 commit comments

Comments
 (0)
Please sign in to comment.