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
This commit is contained in:
Sebastian Dröge 2020-06-21 18:28:04 +03:00
parent c68df282e8
commit 210e7c8777

View file

@ -175,43 +175,43 @@ pub trait PadExtManual: 'static {
fn stream_lock(&self) -> StreamLock; fn stream_lock(&self) -> StreamLock;
fn set_activate_function<F>(&self, func: F) unsafe fn set_activate_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static; F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static;
fn set_activatemode_function<F>(&self, func: F) unsafe fn set_activatemode_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError> F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError>
+ Send + Send
+ Sync + Sync
+ 'static; + 'static;
fn set_chain_function<F>(&self, func: F) unsafe fn set_chain_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError> F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError>
+ Send + Send
+ Sync + Sync
+ 'static; + 'static;
fn set_chain_list_function<F>(&self, func: F) unsafe fn set_chain_list_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError> F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError>
+ Send + Send
+ Sync + Sync
+ 'static; + 'static;
fn set_event_function<F>(&self, func: F) unsafe fn set_event_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static; F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static;
fn set_event_full_function<F>(&self, func: F) unsafe fn set_event_full_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError> F: Fn(&Self, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError>
+ Send + Send
+ Sync + Sync
+ 'static; + 'static;
fn set_getrange_function<F>(&self, func: F) unsafe fn set_getrange_function<F>(&self, func: F)
where where
F: Fn( F: Fn(
&Self, &Self,
@ -224,22 +224,22 @@ pub trait PadExtManual: 'static {
+ Sync + Sync
+ 'static; + 'static;
fn set_iterate_internal_links_function<F>(&self, func: F) unsafe fn set_iterate_internal_links_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static; F: Fn(&Self, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static;
fn set_link_function<F>(&self, func: F) unsafe fn set_link_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError> F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError>
+ Send + Send
+ Sync + Sync
+ 'static; + 'static;
fn set_query_function<F>(&self, func: F) unsafe fn set_query_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static; F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static;
fn set_unlink_function<F>(&self, func: F) unsafe fn set_unlink_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static; F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static;
@ -586,111 +586,97 @@ impl<O: IsA<Pad>> PadExtManual for O {
} }
} }
fn set_activate_function<F>(&self, func: F) unsafe fn set_activate_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static, F: Fn(&Self, Option<&::Object>) -> Result<(), LoggableError> + Send + Sync + 'static,
{ {
#[allow(clippy::type_complexity)] let func_box: Box<F> = Box::new(func);
unsafe { gst_sys::gst_pad_set_activate_function_full(
let func_box: Box<F> = Box::new(func); self.as_ref().to_glib_none().0,
gst_sys::gst_pad_set_activate_function_full( Some(trampoline_activate_function::<Self, F>),
self.as_ref().to_glib_none().0, Box::into_raw(func_box) as gpointer,
Some(trampoline_activate_function::<Self, F>), Some(destroy_closure::<F>),
Box::into_raw(func_box) as gpointer, );
Some(destroy_closure::<F>),
);
}
} }
fn set_activatemode_function<F>(&self, func: F) unsafe fn set_activatemode_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError> F: Fn(&Self, Option<&::Object>, ::PadMode, bool) -> Result<(), LoggableError>
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
{ {
#[allow(clippy::type_complexity)] let func_box: Box<F> = Box::new(func);
unsafe { gst_sys::gst_pad_set_activatemode_function_full(
let func_box: Box<F> = Box::new(func); self.as_ref().to_glib_none().0,
gst_sys::gst_pad_set_activatemode_function_full( Some(trampoline_activatemode_function::<Self, F>),
self.as_ref().to_glib_none().0, Box::into_raw(func_box) as gpointer,
Some(trampoline_activatemode_function::<Self, F>), Some(destroy_closure::<F>),
Box::into_raw(func_box) as gpointer, );
Some(destroy_closure::<F>),
);
}
} }
fn set_chain_function<F>(&self, func: F) unsafe fn set_chain_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError> F: Fn(&Self, Option<&::Object>, ::Buffer) -> Result<FlowSuccess, FlowError>
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_chain_function_full(
gst_sys::gst_pad_set_chain_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_chain_function::<Self, F>),
Some(trampoline_chain_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_chain_list_function<F>(&self, func: F) unsafe fn set_chain_list_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError> F: Fn(&Self, Option<&::Object>, ::BufferList) -> Result<FlowSuccess, FlowError>
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_chain_list_function_full(
gst_sys::gst_pad_set_chain_list_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_chain_list_function::<Self, F>),
Some(trampoline_chain_list_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_event_function<F>(&self, func: F) unsafe fn set_event_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static, F: Fn(&Self, Option<&::Object>, ::Event) -> bool + Send + Sync + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_event_function_full(
gst_sys::gst_pad_set_event_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_event_function::<Self, F>),
Some(trampoline_event_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_event_full_function<F>(&self, func: F) unsafe fn set_event_full_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError> F: Fn(&Self, Option<&::Object>, ::Event) -> Result<FlowSuccess, FlowError>
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_event_full_function_full(
gst_sys::gst_pad_set_event_full_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_event_full_function::<Self, F>),
Some(trampoline_event_full_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_getrange_function<F>(&self, func: F) unsafe fn set_getrange_function<F>(&self, func: F)
where where
F: Fn( F: Fn(
&Self, &Self,
@ -703,78 +689,68 @@ impl<O: IsA<Pad>> PadExtManual for O {
+ Sync + Sync
+ 'static, + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_getrange_function_full(
gst_sys::gst_pad_set_getrange_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_getrange_function::<Self, F>),
Some(trampoline_getrange_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_iterate_internal_links_function<F>(&self, func: F) unsafe fn set_iterate_internal_links_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static, F: Fn(&Self, Option<&::Object>) -> ::Iterator<Pad> + Send + Sync + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_iterate_internal_links_function_full(
gst_sys::gst_pad_set_iterate_internal_links_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_iterate_internal_links_function::<Self, F>),
Some(trampoline_iterate_internal_links_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_link_function<F>(&self, func: F) unsafe fn set_link_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError> F: Fn(&Self, Option<&::Object>, &Pad) -> Result<::PadLinkSuccess, ::PadLinkError>
+ Send + Send
+ Sync + Sync
+ 'static, + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_link_function_full(
gst_sys::gst_pad_set_link_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_link_function::<Self, F>),
Some(trampoline_link_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_query_function<F>(&self, func: F) unsafe fn set_query_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static, F: Fn(&Self, Option<&::Object>, &mut ::QueryRef) -> bool + Send + Sync + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_query_function_full(
gst_sys::gst_pad_set_query_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_query_function::<Self, F>),
Some(trampoline_query_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn set_unlink_function<F>(&self, func: F) unsafe fn set_unlink_function<F>(&self, func: F)
where where
F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static, F: Fn(&Self, Option<&::Object>) + Send + Sync + 'static,
{ {
unsafe { let func_box: Box<F> = Box::new(func);
let func_box: Box<F> = Box::new(func); gst_sys::gst_pad_set_unlink_function_full(
gst_sys::gst_pad_set_unlink_function_full( self.as_ref().to_glib_none().0,
self.as_ref().to_glib_none().0, Some(trampoline_unlink_function::<Self, F>),
Some(trampoline_unlink_function::<Self, F>), Box::into_raw(func_box) as gpointer,
Box::into_raw(func_box) as gpointer, Some(destroy_closure::<F>),
Some(destroy_closure::<F>), );
);
}
} }
fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError> { fn start_task<F: FnMut() + Send + 'static>(&self, func: F) -> Result<(), glib::BoolError> {