forked from mirrors/gstreamer-rs
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:
parent
7b98b2e7da
commit
7c600bfce3
2 changed files with 41 additions and 26 deletions
|
@ -46,18 +46,18 @@ unsafe extern "C" fn trampoline_sync(
|
||||||
func: gpointer,
|
func: gpointer,
|
||||||
) -> ffi::GstBusSyncReply {
|
) -> ffi::GstBusSyncReply {
|
||||||
let _guard = CallbackGuard::new();
|
let _guard = CallbackGuard::new();
|
||||||
let func: &RefCell<Box<FnMut(&Bus, &Message) -> BusSyncReply + 'static>> = transmute(func);
|
let f: &Box<Fn(&Bus, &Message) -> BusSyncReply + 'static> = transmute(func);
|
||||||
(&mut *func.borrow_mut())(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib()
|
f(&from_glib_none(bus), &Message::from_glib_none(msg)).to_glib()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn destroy_closure_sync(ptr: gpointer) {
|
unsafe extern "C" fn destroy_closure_sync(ptr: gpointer) {
|
||||||
let _guard = CallbackGuard::new();
|
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 {
|
fn into_raw_sync<F: Fn(&Bus, &Message) -> BusSyncReply + Send + 'static>(func: F) -> gpointer {
|
||||||
let func: Box<RefCell<Box<FnMut(&Bus, &Message) -> BusSyncReply + Send + 'static>>> =
|
let func: Box<Box<Fn(&Bus, &Message) -> BusSyncReply + Send + 'static>> =
|
||||||
Box::new(RefCell::new(Box::new(func)));
|
Box::new(Box::new(func));
|
||||||
Box::into_raw(func) as gpointer
|
Box::into_raw(func) as gpointer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ impl Bus {
|
||||||
|
|
||||||
pub fn set_sync_handler<F>(&self, func: F)
|
pub fn set_sync_handler<F>(&self, func: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&Bus, &Message) -> BusSyncReply + Send + 'static,
|
F: Fn(&Bus, &Message) -> BusSyncReply + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
ffi::gst_bus_set_sync_handler(
|
ffi::gst_bus_set_sync_handler(
|
||||||
|
|
|
@ -17,7 +17,6 @@ use QueryRef;
|
||||||
use Event;
|
use Event;
|
||||||
use miniobject::MiniObject;
|
use miniobject::MiniObject;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ pub enum PadProbeData<'a> {
|
||||||
pub trait PadExtManual {
|
pub trait PadExtManual {
|
||||||
fn add_probe<F>(&self, mask: PadProbeType, func: F) -> PadProbeId
|
fn add_probe<F>(&self, mask: PadProbeType, func: F) -> PadProbeId
|
||||||
where
|
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 remove_probe(&self, id: PadProbeId);
|
||||||
|
|
||||||
fn chain(&self, buffer: Buffer) -> FlowReturn;
|
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_caps(&self, query: &mut QueryRef) -> bool;
|
||||||
fn proxy_query_accept_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 push_event(&self, event: Event) -> bool;
|
||||||
fn send_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 {
|
impl<O: IsA<Pad>> PadExtManual for O {
|
||||||
fn add_probe<F>(&self, mask: PadProbeType, func: F) -> PadProbeId
|
fn add_probe<F>(&self, mask: PadProbeType, func: F) -> PadProbeId
|
||||||
where
|
where
|
||||||
F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,
|
F: Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let id = ffi::gst_pad_add_probe(
|
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.into();
|
||||||
let parent = parent.to_glib_none();
|
let parent = parent.to_glib_none();
|
||||||
unsafe {
|
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 {
|
fn push_event(&self, event: Event) -> bool {
|
||||||
unsafe {
|
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 {
|
fn send_event(&self, event: Event) -> bool {
|
||||||
unsafe {
|
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,
|
func: gpointer,
|
||||||
) -> ffi::GstPadProbeReturn {
|
) -> ffi::GstPadProbeReturn {
|
||||||
let _guard = CallbackGuard::new();
|
let _guard = CallbackGuard::new();
|
||||||
let func: &RefCell<
|
let func: &Box<Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static> =
|
||||||
Box<FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>,
|
transmute(func);
|
||||||
> = transmute(func);
|
|
||||||
let mut data_type = None;
|
let mut data_type = None;
|
||||||
|
|
||||||
let mut probe_info = PadProbeInfo {
|
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 {
|
match probe_info.data {
|
||||||
Some(PadProbeData::Buffer(buffer)) => {
|
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) {
|
unsafe extern "C" fn destroy_closure_pad_probe(ptr: gpointer) {
|
||||||
let _guard = CallbackGuard::new();
|
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<
|
fn into_raw_pad_probe<F: Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>(
|
||||||
F: FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static,
|
|
||||||
>(
|
|
||||||
func: F,
|
func: F,
|
||||||
) -> gpointer {
|
) -> gpointer {
|
||||||
let func: Box<
|
let func: Box<Box<Fn(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>> =
|
||||||
RefCell<Box<FnMut(&Pad, &mut PadProbeInfo) -> PadProbeReturn + Send + Sync + 'static>>,
|
Box::new(Box::new(func));
|
||||||
> = Box::new(RefCell::new(Box::new(func)));
|
|
||||||
Box::into_raw(func) as gpointer
|
Box::into_raw(func) as gpointer
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue