use pyo3::marker::{Python, Ungil};
mod sealed {
use super::*;
pub trait SealedUnsafeUngilExt {}
impl SealedUnsafeUngilExt for Python<'_> {}
}
#[non_exhaustive]
struct UnsafeUngil<T>(T);
unsafe impl<T> Send for UnsafeUngil<T> {}
impl<T> UnsafeUngil<T> {
pub const unsafe fn new(value: T) -> Self {
Self(value)
}
}
pub trait UnsafeUngilExt: sealed::SealedUnsafeUngilExt {
unsafe fn allow_threads_unsend<T, F, U>(self, ungil: U, f: F) -> T
where
F: Ungil + FnOnce(U) -> T + Send,
T: Ungil;
}
impl UnsafeUngilExt for Python<'_> {
unsafe fn allow_threads_unsend<T, F, U>(self, ungil: U, f: F) -> T
where
F: Ungil + FnOnce(U) -> T + Send,
T: Ungil,
{
let unsafe_ungil = UnsafeUngil::new(ungil);
self.allow_threads(move || {
let unsafe_ungil = unsafe_ungil;
f(unsafe_ungil.0)
})
}
}