Skip to content

Commit 23229ea

Browse files
committed
Use GILProtected to make it explicit where we depend on the GIL for synchronization.
1 parent 4151c25 commit 23229ea

File tree

2 files changed

+10
-16
lines changed

2 files changed

+10
-16
lines changed

src/datetime.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@
5757
//! [scalars-datetime64]: https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.datetime64
5858
//! [scalars-timedelta64]: https://numpy.org/doc/stable/reference/arrays.scalars.html#numpy.timedelta64
5959
60-
use std::cell::UnsafeCell;
60+
use std::cell::RefCell;
6161
use std::collections::hash_map::Entry;
6262
use std::fmt;
6363
use std::hash::Hash;
6464
use std::marker::PhantomData;
6565

66-
use pyo3::{Py, Python};
66+
use pyo3::{sync::GILProtected, Py, Python};
6767
use rustc_hash::FxHashMap;
6868

6969
use crate::dtype::{Element, PyArrayDescr};
@@ -206,32 +206,25 @@ impl<U: Unit> fmt::Debug for Timedelta<U> {
206206

207207
struct TypeDescriptors {
208208
npy_type: NPY_TYPES,
209-
dtypes: UnsafeCell<Option<FxHashMap<NPY_DATETIMEUNIT, Py<PyArrayDescr>>>>,
209+
#[allow(clippy::type_complexity)]
210+
dtypes: GILProtected<RefCell<Option<FxHashMap<NPY_DATETIMEUNIT, Py<PyArrayDescr>>>>>,
210211
}
211212

212-
unsafe impl Sync for TypeDescriptors {}
213-
214213
impl TypeDescriptors {
215214
/// `npy_type` must be either `NPY_DATETIME` or `NPY_TIMEDELTA`.
216215
const unsafe fn new(npy_type: NPY_TYPES) -> Self {
217216
Self {
218217
npy_type,
219-
dtypes: UnsafeCell::new(None),
218+
dtypes: GILProtected::new(RefCell::new(None)),
220219
}
221220
}
222221

223-
#[allow(clippy::mut_from_ref)]
224-
unsafe fn get(&self) -> &mut FxHashMap<NPY_DATETIMEUNIT, Py<PyArrayDescr>> {
225-
(*self.dtypes.get()).get_or_insert_with(Default::default)
226-
}
227-
228222
#[allow(clippy::wrong_self_convention)]
229223
fn from_unit<'py>(&'py self, py: Python<'py>, unit: NPY_DATETIMEUNIT) -> &'py PyArrayDescr {
230-
// SAFETY: We hold the GIL and we do not call into user code which might re-enter.
231-
let dtypes = unsafe { self.get() };
224+
let mut dtypes = self.dtypes.get(py).borrow_mut();
232225

233-
match dtypes.entry(unit) {
234-
Entry::Occupied(entry) => entry.into_mut().as_ref(py),
226+
match dtypes.get_or_insert_with(Default::default).entry(unit) {
227+
Entry::Occupied(entry) => entry.into_mut().clone().into_ref(py),
235228
Entry::Vacant(entry) => {
236229
let dtype = PyArrayDescr::new_from_npy_type(py, self.npy_type);
237230

@@ -244,7 +237,7 @@ impl TypeDescriptors {
244237
metadata.meta.num = 1;
245238
}
246239

247-
entry.insert(dtype.into()).as_ref(py)
240+
entry.insert(dtype.into()).clone().into_ref(py)
248241
}
249242
}
250243
}

src/slice_container.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use pyo3::pyclass;
55

66
/// Utility type to safely store `Box<[_]>` or `Vec<_>` on the Python heap
77
#[pyclass(frozen)]
8+
#[derive(Debug)]
89
pub(crate) struct PySliceContainer {
910
pub(crate) ptr: *mut u8,
1011
pub(crate) len: usize,

0 commit comments

Comments
 (0)