From b468280353ec24b536793e711e55f03e99bc09fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 16 May 2024 16:38:15 +0300 Subject: [PATCH] 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: --- gstreamer-app/src/app_sink.rs | 119 ++++++++++++++++++++---------- gstreamer-app/src/app_src.rs | 72 ++++++++++++------ gstreamer/src/subclass/element.rs | 18 ++++- gstreamer/src/subclass/error.rs | 12 +++ 4 files changed, 156 insertions(+), 65 deletions(-) diff --git a/gstreamer-app/src/app_sink.rs b/gstreamer-app/src/app_sink.rs index 6b15373d8..4d478f6ef 100644 --- a/gstreamer-app/src/app_sink.rs +++ b/gstreamer-app/src/app_sink.rs @@ -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 bool + Send + 'static>>, propose_allocation: Option 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 = from_glib_borrow(appsink); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 = from_glib_borrow(appsink); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 = from_glib_borrow(appsink); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 = from_glib_borrow(appsink); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 = from_glib_borrow(appsink); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 { diff --git a/gstreamer-app/src/app_src.rs b/gstreamer-app/src/app_src.rs index 22ebc8ca6..0e63f9100 100644 --- a/gstreamer-app/src/app_src.rs +++ b/gstreamer-app/src/app_src.rs @@ -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>, enough_data: Option>, seek_data: Option 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 = from_glib_borrow(appsrc); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 = from_glib_borrow(appsrc); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 = from_glib_borrow(appsrc); + #[cfg(not(panic = "abort"))] if (*callbacks).panicked.load(Ordering::Relaxed) { let element: Borrowed = 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 { diff --git a/gstreamer/src/subclass/element.rs b/gstreamer/src/subclass/element.rs index 02c3e7c4b..d740b13e7 100644 --- a/gstreamer/src/subclass/element.rs +++ b/gstreamer/src/subclass/element.rs @@ -286,8 +286,16 @@ pub trait ElementImplExt: sealed::Sealed + ObjectSubclass { #[inline(never)] fn panicked(&self) -> &atomic::AtomicBool { - self.instance_data::(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::(crate::Element::static_type()) + .expect("instance not initialized correctly") + } } fn catch_panic R, G: FnOnce() -> R>(&self, fallback: G, f: F) -> R { @@ -408,6 +416,7 @@ unsafe impl IsSubclassable for Element { fn instance_init(instance: &mut glib::subclass::InitializingObject) { Self::parent_instance_init::(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( _ => 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( diff --git a/gstreamer/src/subclass/error.rs b/gstreamer/src/subclass/error.rs index 79dc31da8..189a3c707 100644 --- a/gstreamer/src/subclass/error.rs +++ b/gstreamer/src/subclass/error.rs @@ -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);