Hack around floating references

By unsetting the floating flag in our virtual method trampolines if it
was set, and resetting it at the end of the function again if it was
set.

Otherwise we can't safely use any bindings, as the assumptions about
floating references are invalid then and things just crash.
This commit is contained in:
Sebastian Dröge 2017-09-24 23:21:15 +03:00
parent 395a002f4a
commit 0423264fea
6 changed files with 51 additions and 2 deletions

View file

@ -194,6 +194,7 @@ where
T::ImplType: BaseSinkImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSink = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -209,6 +210,7 @@ where
T::ImplType: BaseSinkImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSink = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -225,6 +227,7 @@ where
T::ImplType: BaseSinkImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSink = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -244,6 +247,7 @@ where
T::ImplType: BaseSinkImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSink = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -261,6 +265,7 @@ where
T::ImplType: BaseSinkImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSink = from_glib_borrow(ptr);
let imp = &*element.imp;

View file

@ -251,6 +251,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -266,6 +267,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -281,6 +283,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -297,6 +300,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -323,6 +327,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -342,6 +347,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -360,6 +366,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;
@ -377,6 +384,7 @@ where
T::ImplType: BaseSrcImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst_base::BaseSrc = from_glib_borrow(ptr);
let imp = &*element.imp;

View file

@ -169,6 +169,7 @@ where
T::ImplType: ElementImpl,
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: gst::Element = from_glib_borrow(ptr);
let imp = &*element.imp;

View file

@ -31,6 +31,35 @@ macro_rules! callback_guard {
)
}
macro_rules! floating_reference_guard {
($obj:ident) => (
let _guard = $crate::FloatingReferenceGuard::new($obj as *mut _);
)
}
pub struct FloatingReferenceGuard(*mut gobject_ffi::GObject);
impl FloatingReferenceGuard {
pub fn new(obj: *mut gobject_ffi::GObject) -> Option<FloatingReferenceGuard> {
unsafe {
if gobject_ffi::g_object_is_floating(obj) != glib_ffi::GFALSE {
gobject_ffi::g_object_ref_sink(obj);
Some(FloatingReferenceGuard(obj))
} else {
None
}
}
}
}
impl Drop for FloatingReferenceGuard {
fn drop(&mut self) {
unsafe {
gobject_ffi::g_object_force_floating(self.0);
}
}
}
#[macro_use]
pub mod utils;
#[macro_use]

View file

@ -352,6 +352,7 @@ unsafe extern "C" fn get_property<T: ObjectType>(
_pspec: *mut gobject_ffi::GParamSpec,
) {
callback_guard!();
floating_reference_guard!(obj);
match T::get_property(&from_glib_borrow(obj as *mut InstanceStruct<T>), id - 1) {
Ok(v) => {
gobject_ffi::g_value_unset(value);
@ -369,6 +370,7 @@ unsafe extern "C" fn set_property<T: ObjectType>(
_pspec: *mut gobject_ffi::GParamSpec,
) {
callback_guard!();
floating_reference_guard!(obj);
T::set_property(
&from_glib_borrow(obj as *mut InstanceStruct<T>),
id - 1,
@ -456,6 +458,7 @@ unsafe extern "C" fn sub_get_property<T: ObjectType>(
_pspec: *mut gobject_ffi::GParamSpec,
) {
callback_guard!();
floating_reference_guard!(obj);
let instance = &*(obj as *mut InstanceStruct<T>);
let imp = instance.get_impl();
@ -476,6 +479,7 @@ unsafe extern "C" fn sub_set_property<T: ObjectType>(
_pspec: *mut gobject_ffi::GParamSpec,
) {
callback_guard!();
floating_reference_guard!(obj);
let instance = &*(obj as *mut InstanceStruct<T>);
let imp = instance.get_impl();
imp.set_property(
@ -490,8 +494,7 @@ unsafe extern "C" fn sub_init<T: ObjectType>(
_klass: glib_ffi::gpointer,
) {
callback_guard!();
// Get rid of floating reference, if any
gobject_ffi::g_object_ref_sink(obj as *mut gobject_ffi::GObject);
floating_reference_guard!(obj);
let instance = &mut *(obj as *mut InstanceStruct<T>);
let klass = &**(obj as *const *const ClassStruct<T>);
let rs_instance: T::RsType = from_glib_borrow(obj as *mut InstanceStruct<T>);

View file

@ -63,6 +63,8 @@ unsafe extern "C" fn uri_handler_get_uri<T: ObjectType>(
uri_handler: *mut gst_ffi::GstURIHandler,
) -> *mut libc::c_char {
callback_guard!();
floating_reference_guard!(uri_handler);
let klass = &**(uri_handler as *const *const ClassStruct<T>);
let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) as
*const URIHandlerStatic<T>;
@ -80,6 +82,7 @@ unsafe extern "C" fn uri_handler_set_uri<T: ObjectType>(
err: *mut *mut glib_ffi::GError,
) -> glib_ffi::gboolean {
callback_guard!();
floating_reference_guard!(uri_handler);
let klass = &**(uri_handler as *const *const ClassStruct<T>);
let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) as