forked from mirrors/gstreamer-rs
Improve code generation with panic=abort around panic handling code
None of that can ever be called in that case but the compiler can't know that in more complicated cases like these. Handling it explicitly allows no handling code to be generated at all here, like would already happen everywhere else. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1441>
This commit is contained in:
parent
0ef80c4fe7
commit
b468280353
4 changed files with 156 additions and 65 deletions
|
@ -4,13 +4,13 @@ use std::{
|
|||
mem, panic,
|
||||
pin::Pin,
|
||||
ptr,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Mutex,
|
||||
},
|
||||
sync::{Arc, Mutex},
|
||||
task::{Context, Poll, Waker},
|
||||
};
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use futures_core::Stream;
|
||||
use glib::{ffi::gpointer, prelude::*, translate::*};
|
||||
|
||||
|
@ -28,6 +28,7 @@ pub struct AppSinkCallbacks {
|
|||
new_event: Option<Box<dyn FnMut(&AppSink) -> bool + Send + 'static>>,
|
||||
propose_allocation:
|
||||
Option<Box<dyn FnMut(&AppSink, &mut gst::query::Allocation) -> bool + Send + 'static>>,
|
||||
#[cfg(not(panic = "abort"))]
|
||||
panicked: AtomicBool,
|
||||
callbacks: ffi::GstAppSinkCallbacks,
|
||||
}
|
||||
|
@ -194,6 +195,7 @@ impl AppSinkCallbacksBuilder {
|
|||
new_sample: self.new_sample,
|
||||
new_event: self.new_event,
|
||||
propose_allocation: self.propose_allocation,
|
||||
#[cfg(not(panic = "abort"))]
|
||||
panicked: AtomicBool::new(false),
|
||||
callbacks: ffi::GstAppSinkCallbacks {
|
||||
eos: if have_eos { Some(trampoline_eos) } else { None },
|
||||
|
@ -227,6 +229,7 @@ unsafe extern "C" fn trampoline_eos(appsink: *mut ffi::GstAppSink, callbacks: gp
|
|||
let callbacks = callbacks as *mut AppSinkCallbacks;
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -238,12 +241,19 @@ unsafe extern "C" fn trampoline_eos(appsink: *mut ffi::GstAppSink, callbacks: gp
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -256,6 +266,7 @@ unsafe extern "C" fn trampoline_new_preroll(
|
|||
let callbacks = callbacks as *mut AppSinkCallbacks;
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -267,14 +278,21 @@ unsafe extern "C" fn trampoline_new_preroll(
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
|
||||
gst::FlowReturn::Error
|
||||
gst::FlowReturn::Error
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -291,6 +309,7 @@ unsafe extern "C" fn trampoline_new_sample(
|
|||
let callbacks = callbacks as *mut AppSinkCallbacks;
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -302,14 +321,21 @@ unsafe extern "C" fn trampoline_new_sample(
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
|
||||
gst::FlowReturn::Error
|
||||
gst::FlowReturn::Error
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -326,6 +352,7 @@ unsafe extern "C" fn trampoline_new_event(
|
|||
let callbacks = callbacks as *mut AppSinkCallbacks;
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -337,14 +364,21 @@ unsafe extern "C" fn trampoline_new_event(
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
|
||||
false
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -362,6 +396,7 @@ unsafe extern "C" fn trampoline_propose_allocation(
|
|||
let callbacks = callbacks as *mut AppSinkCallbacks;
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSink> = from_glib_borrow(appsink);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -379,14 +414,20 @@ unsafe extern "C" fn trampoline_propose_allocation(
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
|
||||
false
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -4,13 +4,13 @@ use std::{
|
|||
mem, panic,
|
||||
pin::Pin,
|
||||
ptr,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Mutex,
|
||||
},
|
||||
sync::{Arc, Mutex},
|
||||
task::{Context, Poll, Waker},
|
||||
};
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use futures_sink::Sink;
|
||||
use glib::{
|
||||
ffi::{gboolean, gpointer},
|
||||
|
@ -25,6 +25,7 @@ pub struct AppSrcCallbacks {
|
|||
need_data: Option<Box<dyn FnMut(&AppSrc, u32) + Send + 'static>>,
|
||||
enough_data: Option<Box<dyn Fn(&AppSrc) + Send + Sync + 'static>>,
|
||||
seek_data: Option<Box<dyn Fn(&AppSrc, u64) -> bool + Send + Sync + 'static>>,
|
||||
#[cfg(not(panic = "abort"))]
|
||||
panicked: AtomicBool,
|
||||
callbacks: ffi::GstAppSrcCallbacks,
|
||||
}
|
||||
|
@ -120,6 +121,7 @@ impl AppSrcCallbacksBuilder {
|
|||
need_data: self.need_data,
|
||||
enough_data: self.enough_data,
|
||||
seek_data: self.seek_data,
|
||||
#[cfg(not(panic = "abort"))]
|
||||
panicked: AtomicBool::new(false),
|
||||
callbacks: ffi::GstAppSrcCallbacks {
|
||||
need_data: if have_need_data {
|
||||
|
@ -156,6 +158,7 @@ unsafe extern "C" fn trampoline_need_data(
|
|||
let callbacks = callbacks as *mut AppSrcCallbacks;
|
||||
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -167,12 +170,19 @@ unsafe extern "C" fn trampoline_need_data(
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -182,6 +192,7 @@ unsafe extern "C" fn trampoline_enough_data(appsrc: *mut ffi::GstAppSrc, callbac
|
|||
let callbacks = callbacks as *const AppSrcCallbacks;
|
||||
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -193,12 +204,19 @@ unsafe extern "C" fn trampoline_enough_data(appsrc: *mut ffi::GstAppSrc, callbac
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,6 +230,7 @@ unsafe extern "C" fn trampoline_seek_data(
|
|||
let callbacks = callbacks as *const AppSrcCallbacks;
|
||||
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
if (*callbacks).panicked.load(Ordering::Relaxed) {
|
||||
let element: Borrowed<AppSrc> = from_glib_borrow(appsrc);
|
||||
gst::subclass::post_panic_error_message(element.upcast_ref(), element.upcast_ref(), None);
|
||||
|
@ -223,14 +242,21 @@ unsafe extern "C" fn trampoline_seek_data(
|
|||
match result {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
unreachable!("{err:?}");
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
(*callbacks).panicked.store(true, Ordering::Relaxed);
|
||||
gst::subclass::post_panic_error_message(
|
||||
element.upcast_ref(),
|
||||
element.upcast_ref(),
|
||||
Some(err),
|
||||
);
|
||||
|
||||
false
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -286,8 +286,16 @@ pub trait ElementImplExt: sealed::Sealed + ObjectSubclass {
|
|||
|
||||
#[inline(never)]
|
||||
fn panicked(&self) -> &atomic::AtomicBool {
|
||||
self.instance_data::<atomic::AtomicBool>(crate::Element::static_type())
|
||||
.expect("instance not initialized correctly")
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
static DUMMY: atomic::AtomicBool = atomic::AtomicBool::new(false);
|
||||
&DUMMY
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
self.instance_data::<atomic::AtomicBool>(crate::Element::static_type())
|
||||
.expect("instance not initialized correctly")
|
||||
}
|
||||
}
|
||||
|
||||
fn catch_panic<R, F: FnOnce(&Self) -> R, G: FnOnce() -> R>(&self, fallback: G, f: F) -> R {
|
||||
|
@ -408,6 +416,7 @@ unsafe impl<T: ElementImpl> IsSubclassable<T> for Element {
|
|||
fn instance_init(instance: &mut glib::subclass::InitializingObject<T>) {
|
||||
Self::parent_instance_init::<T>(instance);
|
||||
|
||||
#[cfg(not(panic = "abort"))]
|
||||
instance.set_instance_data(Self::static_type(), atomic::AtomicBool::new(false));
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +438,10 @@ unsafe extern "C" fn element_change_state<T: ElementImpl>(
|
|||
_ => StateChangeReturn::Failure,
|
||||
};
|
||||
|
||||
panic_to_error!(imp, fallback, { imp.change_state(transition).into() }).into_glib()
|
||||
panic_to_error!(imp, fallback, {
|
||||
StateChangeReturn::from(imp.change_state(transition))
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn element_request_new_pad<T: ElementImpl>(
|
||||
|
|
|
@ -34,6 +34,18 @@ pub fn post_panic_error_message(
|
|||
macro_rules! panic_to_error(
|
||||
($imp:expr, $ret:expr, $code:block) => {{
|
||||
#[allow(clippy::unused_unit)]
|
||||
#[cfg(panic = "abort")]
|
||||
{
|
||||
if true {
|
||||
#[allow(unused_mut)]
|
||||
let mut closure = || { $code };
|
||||
closure()
|
||||
} else {
|
||||
let _imp = $imp;
|
||||
$ret
|
||||
}
|
||||
}
|
||||
#[cfg(not(panic = "abort"))]
|
||||
{
|
||||
let panicked = $imp.panicked();
|
||||
let element = $crate::glib::subclass::types::ObjectSubclassExt::obj($imp);
|
||||
|
|
Loading…
Reference in a new issue