EpisodeWidget: Do not lock the Proggress struck when running update callbacks.

Previously each time we wanted to inspect the `Progress` struct we
were blocking which was problematic since the downloader also wants
to block to update it.

Now we use try_lock() and if a lock can't be aquired we requeue another
callback. That way we can also be way more aggressive about the interval
in whihc it the callbacks will run.
This commit is contained in:
Jordan Petridis 2018-06-05 14:17:37 +03:00
parent acabb40171
commit 9b0ac5b83d
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6

View File

@ -18,7 +18,7 @@ use manager;
use std::path::Path; use std::path::Path;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex, TryLockError};
lazy_static! { lazy_static! {
static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = { static ref SIZE_OPTS: Arc<size_opts::FileSizeOpts> = {
@ -481,7 +481,7 @@ fn update_progressbar_callback(
progress_bar_helper(&widget, &prog, episode_rowid) progress_bar_helper(&widget, &prog, episode_rowid)
.unwrap_or(glib::Continue(false)) .unwrap_or(glib::Continue(false))
}); });
timeout_add(150, callback); timeout_add(100, callback);
} }
#[allow(if_same_then_else)] #[allow(if_same_then_else)]
@ -490,11 +490,10 @@ fn progress_bar_helper(
prog: &Arc<Mutex<manager::Progress>>, prog: &Arc<Mutex<manager::Progress>>,
episode_rowid: i32, episode_rowid: i32,
) -> Result<glib::Continue, Error> { ) -> Result<glib::Continue, Error> {
let (fraction, downloaded) = { let (fraction, downloaded) = match prog.try_lock() {
let m = prog Ok(guard) => (guard.get_fraction(), guard.get_downloaded()),
.lock() Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)),
.map_err(|_| format_err!("Failed to get a lock on the mutex."))?; Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")),
(m.get_fraction(), m.get_downloaded())
}; };
// I hate floating points. // I hate floating points.
@ -536,7 +535,7 @@ fn update_total_size_callback(widget: &Rc<EpisodeWidget>, prog: &Arc<Mutex<manag
let callback = clone!(prog, widget => move || { let callback = clone!(prog, widget => move || {
total_size_helper(&widget, &prog).unwrap_or(glib::Continue(true)) total_size_helper(&widget, &prog).unwrap_or(glib::Continue(true))
}); });
timeout_add(500, callback); timeout_add(100, callback);
} }
fn total_size_helper( fn total_size_helper(
@ -544,11 +543,10 @@ fn total_size_helper(
prog: &Arc<Mutex<manager::Progress>>, prog: &Arc<Mutex<manager::Progress>>,
) -> Result<glib::Continue, Error> { ) -> Result<glib::Continue, Error> {
// Get the total_bytes. // Get the total_bytes.
let total_bytes = { let total_bytes = match prog.try_lock() {
let m = prog Ok(guard) => guard.get_total_size(),
.lock() Err(TryLockError::WouldBlock) => return Ok(glib::Continue(true)),
.map_err(|_| format_err!("Failed to get a lock on the mutex."))?; Err(TryLockError::Poisoned(_)) => return Err(format_err!("Progress Mutex is poisoned")),
m.get_total_size()
}; };
debug!("Total Size: {}", total_bytes); debug!("Total Size: {}", total_bytes);