forked from mirrors/gstreamer-rs
gstreamer: Add object_lock method to gst::Object
See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/439 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1212>
This commit is contained in:
parent
77866a52df
commit
a021aaa3ce
3 changed files with 78 additions and 0 deletions
|
@ -252,6 +252,7 @@ pub mod functions;
|
|||
pub use crate::functions::*;
|
||||
|
||||
mod utils;
|
||||
pub use crate::utils::ObjectLockGuard;
|
||||
|
||||
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
||||
mod gtype;
|
||||
|
|
|
@ -28,6 +28,8 @@ pub trait GstObjectExtManual: 'static {
|
|||
interval: ClockTime,
|
||||
values: &mut [glib::Value],
|
||||
) -> Result<(), glib::error::BoolError>;
|
||||
|
||||
fn object_lock(&self) -> crate::utils::ObjectLockGuard<Self>;
|
||||
}
|
||||
|
||||
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)]
|
||||
|
|
|
@ -35,3 +35,73 @@ pub trait Displayable {
|
|||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue