From 210e7c8777c3c3bb715505e7882bccf2a0b416fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 21 Jun 2020 18:28:04 +0300 Subject: [PATCH] gstreamer/pad: Mark pad function setters as unsafe This is not thread-safe and changing the function at a bad time will cause crashes or worse. It's only really safe to set the functions right after construction of the pad before any other code can know about it. Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/247 --- gstreamer/src/pad.rs | 222 +++++++++++++++++++------------------------ 1 file changed, 99 insertions(+), 123 deletions(-) diff --git a/gstreamer/src/pad.rs b/gstreamer/src/pad.rs index 9adb420f4..f7103fc7a 100644 --- a/gstreamer/src/pad.rs +++ b/gstreamer/src/pad.rs @@ -175,43 +175,43 @@ pub trait PadExtManual: 'static { fn stream_lock(&self) -> StreamLock; - fn set_activate_function(&self, func: F) + unsafe fn set_activate_function(&self, func: F) where F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static; - fn set_activatemode_function(&self, func: F) + unsafe fn set_activatemode_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError> + Send + Sync + 'static; - fn set_chain_function(&self, func: F) + unsafe fn set_chain_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result + Send + Sync + 'static; - fn set_chain_list_function(&self, func: F) + unsafe fn set_chain_list_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result + Send + Sync + 'static; - fn set_event_function(&self, func: F) + unsafe fn set_event_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static; - fn set_event_full_function(&self, func: F) + unsafe fn set_event_full_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::Event) -> Result + Send + Sync + 'static; - fn set_getrange_function(&self, func: F) + unsafe fn set_getrange_function(&self, func: F) where F: Fn( &Self, @@ -224,22 +224,22 @@ pub trait PadExtManual: 'static { + Sync + 'static; - fn set_iterate_internal_links_function(&self, func: F) + unsafe fn set_iterate_internal_links_function(&self, func: F) where F: Fn(&Self, Option<&::Object>) -> ::Iterator + Send + Sync + 'static; - fn set_link_function(&self, func: F) + unsafe fn set_link_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError> + Send + Sync + 'static; - fn set_query_function(&self, func: F) + unsafe fn set_query_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static; - fn set_unlink_function(&self, func: F) + unsafe fn set_unlink_function(&self, func: F) where F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static; @@ -586,111 +586,97 @@ impl> PadExtManual for O { } } - fn set_activate_function(&self, func: F) + unsafe fn set_activate_function(&self, func: F) where F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static, { - #[allow(clippy::type_complexity)] - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_activate_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_activate_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_activate_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_activate_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_activatemode_function(&self, func: F) + unsafe fn set_activatemode_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError> + Send + Sync + 'static, { - #[allow(clippy::type_complexity)] - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_activatemode_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_activatemode_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_activatemode_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_activatemode_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_chain_function(&self, func: F) + unsafe fn set_chain_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_chain_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_chain_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_chain_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_chain_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_chain_list_function(&self, func: F) + unsafe fn set_chain_list_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_chain_list_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_chain_list_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_chain_list_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_chain_list_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_event_function(&self, func: F) + unsafe fn set_event_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_event_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_event_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_event_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_event_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_event_full_function(&self, func: F) + unsafe fn set_event_full_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, ::Event) -> Result + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_event_full_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_event_full_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_event_full_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_event_full_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_getrange_function(&self, func: F) + unsafe fn set_getrange_function(&self, func: F) where F: Fn( &Self, @@ -703,78 +689,68 @@ impl> PadExtManual for O { + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_getrange_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_getrange_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_getrange_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_getrange_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_iterate_internal_links_function(&self, func: F) + unsafe fn set_iterate_internal_links_function(&self, func: F) where F: Fn(&Self, Option<&::Object>) -> ::Iterator + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_iterate_internal_links_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_iterate_internal_links_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_iterate_internal_links_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_iterate_internal_links_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_link_function(&self, func: F) + unsafe fn set_link_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError> + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_link_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_link_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_link_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_link_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_query_function(&self, func: F) + unsafe fn set_query_function(&self, func: F) where F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_query_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_query_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_query_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_query_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } - fn set_unlink_function(&self, func: F) + unsafe fn set_unlink_function(&self, func: F) where F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static, { - unsafe { - let func_box: Box = Box::new(func); - gst_sys::gst_pad_set_unlink_function_full( - self.as_ref().to_glib_none().0, - Some(trampoline_unlink_function::), - Box::into_raw(func_box) as gpointer, - Some(destroy_closure::), - ); - } + let func_box: Box = Box::new(func); + gst_sys::gst_pad_set_unlink_function_full( + self.as_ref().to_glib_none().0, + Some(trampoline_unlink_function::), + Box::into_raw(func_box) as gpointer, + Some(destroy_closure::), + ); } fn start_task(&self, func: F) -> Result<(), glib::BoolError> {