Skip to content

Commit cc109bf

Browse files
committed
Add deadlock-avoidance using direct FFI calls
1 parent 177927c commit cc109bf

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

src/strings.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,24 @@ impl TypeDescriptors {
178178
byteorder: c_char,
179179
size: usize,
180180
) -> Bound<'py, PyArrayDescr> {
181-
// FIXME probably a deadlock risk here due to the GIL? Might need MutexExt trait in PyO3
181+
// FIXME create a proper MutexExt trait that handles poisoning and upstream to PyO3
182+
struct Guard(*mut pyo3::ffi::PyThreadState);
183+
184+
impl Drop for Guard {
185+
fn drop(&mut self) {
186+
unsafe { pyo3::ffi::PyEval_RestoreThread(self.0) };
187+
}
188+
}
189+
190+
// we are currently attached to the python runtime and we might block trying to acquire
191+
// the dtype cache mutex, so detach to avoid a possible deadlock.
192+
let ts_guard = Guard(unsafe { pyo3::ffi::PyEval_SaveThread() });
193+
182194
let mut dtypes = self.dtypes.lock().expect("dtype cache poisoned");
183195

196+
// we've acquire the dtype cache lock so it's safe to re-attach to the runtime
197+
drop(ts_guard);
198+
184199
let dtype = match dtypes.get_or_insert_with(Default::default).entry(size) {
185200
Entry::Occupied(entry) => entry.into_mut(),
186201
Entry::Vacant(entry) => {

0 commit comments

Comments
 (0)