Skip to content

Potential enhancement: GIL-based Mutex #1877

@itamarst

Description

@itamarst

I have found myself creating statics that are accessed only by threads that have the GIL. As such, use of a normal Mutex is unnecessary performance overhead (and this matters somewhat in my use case, a profiler).

There is Py<T>, but that assumes T is a Python object, so random Rust objects are harder.

So, here is a sketch of a GIL-based Mutex:

/// Protect access to an object such that it can only be accessed when the GIL
/// is held.
pub struct GilMutex<T: ?Sized> {
    data: std::cell::RefCell<T>,
}

unsafe impl<T: ?Sized + Send> Sync for GilMutex<T> {}

pub struct GilRefMut<'p, 's, T: ?Sized> {
    inner: std::cell::RefMut<'s, T>,
    _py: Python<'p>,
}

impl<T: ?Sized> Deref for GilRefMut<'_, '_, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        &self.inner
    }
}

impl<T: ?Sized> DerefMut for GilRefMut<'_, '_, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        self.inner.borrow_mut()
    }
}

impl<T> GilMutex<T> {
    /// Create a new mutex.
    pub const fn new(t: T) -> Self {
        GilMutex {
            data: std::cell::RefCell::new(t),
        }
    }

    /// Get a mutable reference to the data, protected by the GIL.
    pub fn lock<'p, 's>(&'s self, py: Python<'p>) -> GilRefMut<'p, 's, T> {
        GilRefMut {
            inner: self.data.borrow_mut(),
            _py: py,
        }
    }
}
  1. Does this sound generally useful enough to add to PyO3?
  2. Is this code sound? I don't know enough Rust to be certain.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions