From 022b9d072e675d51c14603e37ee776dfe722771e Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Wed, 20 Apr 2022 01:24:24 +0200 Subject: [PATCH] provider image: properly abort old tasks --- Cargo.lock | 1 - Cargo.toml | 1 - src/widgets/providers/image.rs | 46 ++++++++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf85251..ef9f476 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -249,7 +249,6 @@ dependencies = [ "binascii", "diesel", "diesel_migrations", - "futures", "gettext-rs", "gst-plugin-gtk4", "gstreamer", diff --git a/Cargo.toml b/Cargo.toml index d45aa56..93fa6cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ ashpd = {version = "0.3", features = ["feature_pipewire", "feature_gtk4"]} binascii = "0.1" diesel = {version = "1.4", features = ["sqlite", "r2d2"]} diesel_migrations = {version = "1.4", features = ["sqlite"]} -futures = "0.3" gettext-rs = {version = "0.7", features = ["gettext-system"]} gst = {package = "gstreamer", version = "0.18"} gst4gtk = { package = "gst-plugin-gtk4", version = "0.1"} diff --git a/src/widgets/providers/image.rs b/src/widgets/providers/image.rs index 381a01f..1e8c993 100644 --- a/src/widgets/providers/image.rs +++ b/src/widgets/providers/image.rs @@ -27,6 +27,8 @@ mod imp { pub image: TemplateChild, #[template_child] pub spinner: TemplateChild, + pub signal_id: RefCell>, + pub join_handle: RefCell>>, } #[glib::object_subclass] @@ -46,6 +48,8 @@ mod imp { image: TemplateChild::default(), spinner: TemplateChild::default(), provider: RefCell::new(None), + signal_id: Default::default(), + join_handle: Default::default(), } } @@ -132,13 +136,20 @@ impl ProviderImage { imp.spinner.start(); self.on_provider_image_changed(); } - provider.connect_notify_local( + let signal_id = provider.connect_notify_local( Some("image-uri"), clone!(@weak self as image => move |_, _| { image.on_provider_image_changed(); }), ); + imp.signal_id.replace(Some(signal_id)); return; + } else { + if let (Some(signal_id), Some(provider)) = + (imp.signal_id.borrow_mut().take(), self.provider()) + { + provider.disconnect(signal_id); + } } imp.image.set_from_icon_name(Some("provider-fallback")); @@ -179,6 +190,9 @@ impl ProviderImage { fn fetch(&self) { let imp = self.imp(); + if let Some(handle) = imp.join_handle.borrow_mut().take() { + handle.abort(); + } if let Some(provider) = self.provider() { imp.stack.set_visible_child_name("loading"); imp.spinner.start(); @@ -186,8 +200,8 @@ impl ProviderImage { if let Some(website) = provider.website() { let id = provider.id(); let name = provider.name(); - let (sender, receiver) = futures::channel::oneshot::channel(); - RUNTIME.spawn(async move { + let (sender, receiver) = tokio::sync::oneshot::channel(); + let future = async move { match Provider::favicon(website, name, id).await { Ok(cache_name) => { sender.send(Some(cache_name)).unwrap(); @@ -196,16 +210,24 @@ impl ProviderImage { log::error!("Failed to load favicon {}", err); sender.send(None).unwrap(); } - } - }); + }; + }; + let join_handle = RUNTIME.spawn(future); + imp.join_handle.borrow_mut().replace(join_handle); + glib::MainContext::default().spawn_local(clone!(@weak self as this => async move { let imp = this.imp(); - let response = receiver.await.unwrap(); - if let Some(cache_name) = response { - send!(imp.sender.clone(), ImageAction::Ready(cache_name)); - } else { - send!(imp.sender.clone(), ImageAction::Failed); - } + match receiver.await { + Ok(Some(cache_name)) => { + send!(imp.sender.clone(), ImageAction::Ready(cache_name)); + } + Ok(None) => { + send!(imp.sender.clone(), ImageAction::Failed); + }, + Err(_) => { + log::debug!("Provider image fetching aborted"); + } + }; })); } } @@ -261,9 +283,11 @@ impl ProviderImage { } }; if let Some(provider) = self.provider() { + let guard = provider.freeze_notify(); if let Err(err) = provider.set_image_uri(&image_path) { warn!("Failed to update provider image {}", err); } + drop(guard); } imp.stack.set_visible_child_name("image");