From 7c600bfce38a43c27edf3b0823bc8799dda1a2dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 1 Aug 2017 15:28:36 +0100 Subject: [PATCH] Fix unsafety of pad probes and sync bus handler These can't be FnMut but must be Fn as they can be called from many threads at the same time. --- gstreamer/src/bus.rs | 14 ++++++------ gstreamer/src/pad.rs | 53 ++++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/gstreamer/src/bus.rs b/gstreamer/src/bus.rs index 879806829..a0d66332b 100644 --- a/gstreamer/src/bus.rs +++ b/gstreamer/src/bus.rs @@ -46,18 +46,18 @@ unsafe extern "C" fn trampoline_sync( func: gpointer, ) -> ffi::GstBusSyncReply { let _guard = CallbackGuard::new(); - let func: &RefCell BusSyncReply + 'static>> = transmute(func); - (&mut *func.borrow_mut())(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib() + let f: &Box BusSyncReply + 'static> = transmute(func); + f(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib() } unsafe extern "C" fn destroy_closure_sync(ptr: gpointer) { let _guard = CallbackGuard::new(); - Box:: BusSyncReply + 'static>>>::from_raw(ptr as *mut _); + Box:: BusSyncReply + 'static>>::from_raw(ptr as *mut _); } -fn into_raw_sync BusSyncReply + Send + 'static>(func: F) -> gpointer { - let func: Box BusSyncReply + Send + 'static>>> = - Box::new(RefCell::new(Box::new(func))); +fn into_raw_sync BusSyncReply + Send + 'static>(func: F) -> gpointer { + let func: Box BusSyncReply + Send + 'static>> = + Box::new(Box::new(func)); Box::into_raw(func) as gpointer } @@ -108,7 +108,7 @@ impl Bus { pub fn set_sync_handler(&self, func: F) where - F: FnMut(&Bus, &Message) -> BusSyncReply + Send + 'static, + F: Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static, { unsafe { ffi::gst_bus_set_sync_handler( diff --git a/gstreamer/src/pad.rs b/gstreamer/src/pad.rs index d09cec5c3..f2323c6bd 100644 --- a/gstreamer/src/pad.rs +++ b/gstreamer/src/pad.rs @@ -17,7 +17,6 @@ use QueryRef; use Event; use miniobject::MiniObject; -use std::cell::RefCell; use std::mem::transmute; use std::ptr; @@ -68,7 +67,7 @@ pub enum PadProbeData<'a> { pub trait PadExtManual { fn add_probe(&self, mask: PadProbeType, func: F) -> PadProbeId where - F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static; + F: Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static; fn remove_probe(&self, id: PadProbeId); fn chain(&self, buffer: Buffer) -> FlowReturn; @@ -87,7 +86,11 @@ pub trait PadExtManual { fn proxy_query_caps(&self, query: &mut QueryRef) -> bool; fn proxy_query_accept_caps(&self, query: &mut QueryRef) -> bool; - fn event_default<'a, P: IsA<::Object> + 'a, Q: Into>>(&self, parent: Q, event: Event) -> bool; + fn event_default<'a, P: IsA<::Object> + 'a, Q: Into>>( + &self, + parent: Q, + event: Event, + ) -> bool; fn push_event(&self, event: Event) -> bool; fn send_event(&self, event: Event) -> bool; } @@ -95,7 +98,7 @@ pub trait PadExtManual { impl> PadExtManual for O { fn add_probe(&self, mask: PadProbeType, func: F) -> PadProbeId where - F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static, + F: Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static, { unsafe { let id = ffi::gst_pad_add_probe( @@ -210,23 +213,37 @@ impl> PadExtManual for O { } } - fn event_default<'a, P: IsA<::Object> + 'a, Q: Into>>(&self, parent: Q, event: Event) -> bool { + fn event_default<'a, P: IsA<::Object> + 'a, Q: Into>>( + &self, + parent: Q, + event: Event, + ) -> bool { let parent = parent.into(); let parent = parent.to_glib_none(); unsafe { - from_glib(ffi::gst_pad_event_default(self.to_glib_none().0, parent.0, event.into_ptr())) + from_glib(ffi::gst_pad_event_default( + self.to_glib_none().0, + parent.0, + event.into_ptr(), + )) } } fn push_event(&self, event: Event) -> bool { unsafe { - from_glib(ffi::gst_pad_push_event(self.to_glib_none().0, event.into_ptr())) + from_glib(ffi::gst_pad_push_event( + self.to_glib_none().0, + event.into_ptr(), + )) } } fn send_event(&self, event: Event) -> bool { unsafe { - from_glib(ffi::gst_pad_send_event(self.to_glib_none().0, event.into_ptr())) + from_glib(ffi::gst_pad_send_event( + self.to_glib_none().0, + event.into_ptr(), + )) } } } @@ -237,9 +254,8 @@ unsafe extern "C" fn trampoline_pad_probe( func: gpointer, ) -> ffi::GstPadProbeReturn { let _guard = CallbackGuard::new(); - let func: &RefCell< - Box PadProbeReturn + Send + Sync + 'static>, - > = transmute(func); + let func: &Box PadProbeReturn + Send + Sync + 'static> = + transmute(func); let mut data_type = None; let mut probe_info = PadProbeInfo { @@ -277,7 +293,7 @@ unsafe extern "C" fn trampoline_pad_probe( }, }; - let ret = (&mut *func.borrow_mut())(&from_glib_none(pad), &mut probe_info).to_glib(); + let ret = func(&from_glib_none(pad), &mut probe_info).to_glib(); match probe_info.data { Some(PadProbeData::Buffer(buffer)) => { @@ -316,16 +332,15 @@ unsafe extern "C" fn trampoline_pad_probe( unsafe extern "C" fn destroy_closure_pad_probe(ptr: gpointer) { let _guard = CallbackGuard::new(); - Box:: PadProbeReturn + Send + Sync + 'static>>>::from_raw(ptr as *mut _); + Box:: PadProbeReturn + Send + Sync + 'static>>::from_raw( + ptr as *mut _, + ); } -fn into_raw_pad_probe< - F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static, ->( +fn into_raw_pad_probe PadProbeReturn + Send + Sync + 'static>( func: F, ) -> gpointer { - let func: Box< - RefCell PadProbeReturn + Send + Sync + 'static>>, - > = Box::new(RefCell::new(Box::new(func))); + let func: Box PadProbeReturn + Send + Sync + 'static>> = + Box::new(Box::new(func)); Box::into_raw(func) as gpointer }