uriplaylistbin: break reference cycle

Passing ownership of item to the probe callback was introducing a reference cycle as the item is owning the sinkpad.
This commit is contained in:
Guillaume Desmottes 2022-04-08 15:33:00 +02:00
parent ffdcc8167c
commit cde5fdf202

View file

@ -6,8 +6,8 @@
// //
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use std::sync::Arc;
use std::sync::{mpsc, Mutex, MutexGuard}; use std::sync::{mpsc, Mutex, MutexGuard};
use std::sync::{Arc, Weak};
use gst::glib; use gst::glib;
use gst::prelude::*; use gst::prelude::*;
@ -620,6 +620,14 @@ impl Item {
_ => panic!("invalid state: {:?}", inner.state), _ => panic!("invalid state: {:?}", inner.state),
} }
} }
fn downgrade(&self) -> Weak<Mutex<ItemInner>> {
Arc::downgrade(&self.inner)
}
fn upgrade(weak: &Weak<Mutex<ItemInner>>) -> Option<Item> {
weak.upgrade().map(|inner| Item { inner })
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -1414,7 +1422,8 @@ impl UriPlaylistBin {
// block pad until next item is reaching the `Blocked` state // block pad until next item is reaching the `Blocked` state
let receiver = Mutex::new(item.receiver()); let receiver = Mutex::new(item.receiver());
let element_weak = element.downgrade(); let element_weak = element.downgrade();
let item_clone = item.clone(); // passing ownership of item to the probe callback would introduce a reference cycle as the item is owning the sinkpad
let item_weak = item.downgrade();
sink_pad.add_probe(gst::PadProbeType::BLOCK_DOWNSTREAM, move |pad, info| { sink_pad.add_probe(gst::PadProbeType::BLOCK_DOWNSTREAM, move |pad, info| {
let element = match element_weak.upgrade() { let element = match element_weak.upgrade() {
@ -1422,7 +1431,10 @@ impl UriPlaylistBin {
None => return gst::PadProbeReturn::Remove, None => return gst::PadProbeReturn::Remove,
}; };
let parent = pad.parent().unwrap(); let parent = pad.parent().unwrap();
let item = &item_clone; let item = match Item::upgrade(&item_weak) {
Some(item) => item,
None => return gst::PadProbeReturn::Remove,
};
if !item.is_streaming() { if !item.is_streaming() {
// block pad until next item is ready // block pad until next item is ready