Anders Hellerup Madsen 2023-02-05 17:55:32 +01:00 committed by Sebastian Dröge
parent 77866a52df
commit a021aaa3ce
3 changed files with 78 additions and 0 deletions

View file

@ -252,6 +252,7 @@ pub mod functions;
pub use crate::functions::*; pub use crate::functions::*;
mod utils; mod utils;
pub use crate::utils::ObjectLockGuard;
#[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg(any(feature = "v1_18", feature = "dox"))]
mod gtype; mod gtype;

View file

@ -28,6 +28,8 @@ pub trait GstObjectExtManual: 'static {
interval: ClockTime, interval: ClockTime,
values: &mut [glib::Value], values: &mut [glib::Value],
) -> Result<(), glib::error::BoolError>; ) -> Result<(), glib::error::BoolError>;
fn object_lock(&self) -> crate::utils::ObjectLockGuard<Self>;
} }
impl<O: IsA<crate::Object>> GstObjectExtManual for O { impl<O: IsA<crate::Object>> GstObjectExtManual for O {
@ -118,6 +120,11 @@ impl<O: IsA<crate::Object>> GstObjectExtManual for O {
) )
} }
} }
#[inline]
fn object_lock(&self) -> crate::utils::ObjectLockGuard<Self> {
crate::utils::ObjectLockGuard::acquire(self)
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -35,3 +35,73 @@ pub trait Displayable {
fn display(self) -> Self::DisplayImpl; fn display(self) -> Self::DisplayImpl;
} }
#[must_use = "if unused the object lock will immediately be released"]
pub struct ObjectLockGuard<'a, T: ?Sized> {
obj: &'a T,
mutex: &'a mut glib::ffi::GMutex,
}
impl<'a, T> ObjectLockGuard<'a, T>
where
T: glib::IsA<crate::Object> + ?Sized,
{
#[inline]
pub fn acquire(obj: &'a T) -> ObjectLockGuard<'a, T> {
skip_assert_initialized!();
unsafe {
use glib::ObjectType;
let mutex = &mut (*obj.as_ref().as_ptr()).lock;
glib::ffi::g_mutex_lock(mutex);
Self { obj, mutex }
}
}
}
impl<T> AsRef<T> for ObjectLockGuard<'_, T> {
#[inline]
fn as_ref(&self) -> &T {
self.obj
}
}
impl<T> std::ops::Deref for ObjectLockGuard<'_, T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
self.obj
}
}
impl<T> std::fmt::Debug for ObjectLockGuard<'_, T>
where
T: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.obj.fmt(f)
}
}
impl<T> std::cmp::PartialEq for ObjectLockGuard<'_, T>
where
T: std::cmp::PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.obj.eq(other)
}
}
impl<T> std::cmp::Eq for ObjectLockGuard<'_, T> where T: std::cmp::Eq {}
impl<T> Drop for ObjectLockGuard<'_, T>
where
T: ?Sized,
{
#[inline]
fn drop(&mut self) {
unsafe {
glib::ffi::g_mutex_unlock(self.mutex);
}
}
}