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.
This commit is contained in:
Sebastian Dröge 2017-08-01 15:28:36 +01:00
parent 7b98b2e7da
commit 7c600bfce3
2 changed files with 41 additions and 26 deletions

View file

@ -46,18 +46,18 @@ unsafe extern "C" fn trampoline_sync(
func: gpointer,
) -> ffi::GstBusSyncReply {
let _guard = CallbackGuard::new();
let func: &RefCell<Box<FnMut(&Bus, &Message) -> BusSyncReply + 'static>> = transmute(func);
(&mut *func.borrow_mut())(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib()
let f: &Box<Fn(&Bus, &Message) -> 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::<RefCell<Box<FnMut(&Bus, &Message) -> BusSyncReply + 'static>>>::from_raw(ptr as *mut _);
Box::<Box<Fn(&Bus, &Message) -> BusSyncReply + 'static>>::from_raw(ptr as *mut _);
}
fn into_raw_sync<F: FnMut(&Bus, &Message) -> BusSyncReply + Send + 'static>(func: F) -> gpointer {
let func: Box<RefCell<Box<FnMut(&Bus, &Message) -> BusSyncReply + Send + 'static>>> =
Box::new(RefCell::new(Box::new(func)));
fn into_raw_sync<F: Fn(&Bus, &Message) -> BusSyncReply + Send + 'static>(func: F) -> gpointer {
let func: Box<Box<Fn(&Bus, &Message) -> 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<F>(&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(

View file

@ -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<F>(&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<Option<&'a P>>>(&self, parent: Q, event: Event) -> bool;
fn event_default<'a, P: IsA<::Object> + 'a, Q: Into<Option<&'a P>>>(
&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<O: IsA<Pad>> PadExtManual for O {
fn add_probe<F>(&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<O: IsA<Pad>> PadExtManual for O {
}
}
fn event_default<'a, P: IsA<::Object> + 'a, Q: Into<Option<&'a P>>>(&self, parent: Q, event: Event) -> bool {
fn event_default<'a, P: IsA<::Object> + 'a, Q: Into<Option<&'a P>>>(
&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<FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>,
> = transmute(func);
let func: &Box<Fn(&Pad, &mut PadProbeInfo) -> 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::<RefCell<Box<FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>>>::from_raw(ptr as *mut _);
Box::<Box<Fn(&Pad, &mut PadProbeInfo) -> 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<F: Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>(
func: F,
) -> gpointer {
let func: Box<
RefCell<Box<FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>>,
> = Box::new(RefCell::new(Box::new(func)));
let func: Box<Box<Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>> =
Box::new(Box::new(func));
Box::into_raw(func) as gpointer
}