Use atomic_bool for dirty flag

This commit is contained in:
Stephen Seo 2021-09-20 22:44:04 +09:00
parent 76372e4f97
commit e45c214be9

View file

@ -5,7 +5,10 @@ use std::convert::TryInto;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream}; use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream};
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex}; use std::sync::{
atomic::{AtomicBool, Ordering},
Arc, Mutex,
};
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use structopt::StructOpt; use structopt::StructOpt;
@ -55,7 +58,6 @@ struct Shared {
thread_running: bool, thread_running: bool,
stream: TcpStream, stream: TcpStream,
password: String, password: String,
dirty: bool,
can_authenticate: bool, can_authenticate: bool,
can_get_album_art: bool, can_get_album_art: bool,
can_get_album_art_in_dir: bool, can_get_album_art_in_dir: bool,
@ -76,7 +78,6 @@ impl Shared {
thread_running: true, thread_running: true,
stream, stream,
password: String::new(), password: String::new(),
dirty: true,
can_authenticate: true, can_authenticate: true,
can_get_album_art: true, can_get_album_art: true,
can_get_album_art_in_dir: true, can_get_album_art_in_dir: true,
@ -271,7 +272,7 @@ fn read_line(
// Ok(()) // Ok(())
//} //}
fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> { fn info_loop(shared_data: Arc<Mutex<Shared>>, dirty_flag: Arc<AtomicBool>) -> Result<(), String> {
let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE]; let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
let mut init: bool = true; let mut init: bool = true;
let mut saved: Vec<u8> = Vec::new(); let mut saved: Vec<u8> = Vec::new();
@ -311,7 +312,7 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
count = read_vec.len(); count = read_vec.len();
current_binary_size = 0; current_binary_size = 0;
poll_state = PollState::None; poll_state = PollState::None;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
//println!( //println!(
// "art_data len is {} after fully reading", // "art_data len is {} after fully reading",
// lock.art_data.len() // lock.art_data.len()
@ -348,14 +349,14 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
PollState::ReadPicture => { PollState::ReadPicture => {
if lock.art_data.is_empty() { if lock.art_data.is_empty() {
lock.can_get_album_art = false; lock.can_get_album_art = false;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
println!("No embedded album art"); println!("No embedded album art");
} }
} }
PollState::ReadPictureInDir => { PollState::ReadPictureInDir => {
if lock.art_data.is_empty() { if lock.art_data.is_empty() {
lock.can_get_album_art_in_dir = false; lock.can_get_album_art_in_dir = false;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
println!("No album art in dir"); println!("No album art in dir");
} }
} }
@ -368,20 +369,20 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
match poll_state { match poll_state {
PollState::Password => { PollState::Password => {
lock.can_authenticate = false; lock.can_authenticate = false;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
} }
PollState::CurrentSong | PollState::Status => { PollState::CurrentSong | PollState::Status => {
lock.can_get_status = false; lock.can_get_status = false;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
} }
PollState::ReadPicture => { PollState::ReadPicture => {
lock.can_get_album_art = false; lock.can_get_album_art = false;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
println!("Failed to get readpicture"); println!("Failed to get readpicture");
} }
PollState::ReadPictureInDir => { PollState::ReadPictureInDir => {
lock.can_get_album_art_in_dir = false; lock.can_get_album_art_in_dir = false;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
println!("Failed to get albumart"); println!("Failed to get albumart");
} }
_ => (), _ => (),
@ -403,13 +404,13 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
did_check_overtime = false; did_check_overtime = false;
force_get_status = true; force_get_status = true;
} }
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
song_title_get_time = Instant::now(); song_title_get_time = Instant::now();
} else if line.starts_with("elapsed: ") { } else if line.starts_with("elapsed: ") {
let parse_pos_result = f64::from_str(&line.split_off(9)); let parse_pos_result = f64::from_str(&line.split_off(9));
if let Ok(value) = parse_pos_result { if let Ok(value) = parse_pos_result {
lock.current_song_position = value; lock.current_song_position = value;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
song_pos_get_time = Instant::now(); song_pos_get_time = Instant::now();
lock.current_song_pos_rec = Instant::now(); lock.current_song_pos_rec = Instant::now();
} else { } else {
@ -419,14 +420,14 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
let parse_pos_result = f64::from_str(&line.split_off(10)); let parse_pos_result = f64::from_str(&line.split_off(10));
if let Ok(value) = parse_pos_result { if let Ok(value) = parse_pos_result {
lock.current_song_length = value; lock.current_song_length = value;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
song_length_get_time = Instant::now(); song_length_get_time = Instant::now();
} }
} else if line.starts_with("size: ") { } else if line.starts_with("size: ") {
let parse_artsize_result = usize::from_str(&line.split_off(6)); let parse_artsize_result = usize::from_str(&line.split_off(6));
if let Ok(value) = parse_artsize_result { if let Ok(value) = parse_artsize_result {
lock.art_data_size = value; lock.art_data_size = value;
lock.dirty = true; dirty_flag.store(true, Ordering::Relaxed);
} }
} else if line.starts_with("binary: ") { } else if line.starts_with("binary: ") {
let parse_artbinarysize_result = let parse_artbinarysize_result =
@ -540,10 +541,7 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
Ok(()) Ok(())
} }
fn get_info_from_shared( fn get_info_from_shared(shared: Arc<Mutex<Shared>>) -> Result<InfoFromShared, ()> {
shared: Arc<Mutex<Shared>>,
force_check: bool,
) -> Result<InfoFromShared, ()> {
let mut filename: String = String::new(); let mut filename: String = String::new();
let mut title: String = String::new(); let mut title: String = String::new();
let mut artist: String = String::new(); let mut artist: String = String::new();
@ -551,27 +549,22 @@ fn get_info_from_shared(
let mut pos: f64 = 0.0; let mut pos: f64 = 0.0;
let mut instant_rec: Instant = Instant::now(); let mut instant_rec: Instant = Instant::now();
let mut error_text = String::new(); let mut error_text = String::new();
if let Ok(mut lock) = shared.lock() { if let Ok(lock) = shared.lock() {
if lock.dirty || force_check { filename = lock.current_song_filename.clone();
filename = lock.current_song_filename.clone(); title = lock.current_song_title.clone();
title = lock.current_song_title.clone(); artist = lock.current_song_artist.clone();
artist = lock.current_song_artist.clone(); length = lock.current_song_length;
length = lock.current_song_length; pos = lock.current_song_position;
pos = lock.current_song_position; instant_rec = lock.current_song_pos_rec;
instant_rec = lock.current_song_pos_rec; //println!("Current song: {}", lock.current_song_filename);
//println!("Current song: {}", lock.current_song_filename); //println!("Current song length: {}", lock.current_song_length);
//println!("Current song length: {}", lock.current_song_length); //println!("Current song position: {}", lock.current_song_position);
//println!("Current song position: {}", lock.current_song_position); if !lock.can_authenticate {
if !lock.can_authenticate { error_text = String::from("Failed to authenticate to mpd");
error_text = String::from("Failed to authenticate to mpd"); } else if !lock.can_get_status {
} else if !lock.can_get_status { error_text = String::from("Failed to get status from mpd");
error_text = String::from("Failed to get status from mpd"); } else if !lock.can_get_album_art && !lock.can_get_album_art_in_dir {
} else if !lock.can_get_album_art && !lock.can_get_album_art_in_dir { error_text = String::from("Failed to get albumart from mpd");
error_text = String::from("Failed to get albumart from mpd");
}
lock.dirty = false;
} else {
return Err(());
} }
} }
@ -689,10 +682,12 @@ async fn main() -> Result<(), String> {
.expect("Should be able to get mutex lock") .expect("Should be able to get mutex lock")
.password = p; .password = p;
} }
let atomic_dirty_flag = Arc::new(AtomicBool::new(true));
let thread_shared_data = shared_data.clone(); let thread_shared_data = shared_data.clone();
let thread_dirty_flag = atomic_dirty_flag.clone();
let child = thread::spawn(move || { let child = thread::spawn(move || {
info_loop(thread_shared_data).expect("Failure during info_loop"); info_loop(thread_shared_data, thread_dirty_flag).expect("Failure during info_loop");
}); });
let mut timer: f64 = 0.0; let mut timer: f64 = 0.0;
@ -743,32 +738,38 @@ async fn main() -> Result<(), String> {
//println!("check_due_to_track_timer_count incremented"); // DEBUG //println!("check_due_to_track_timer_count incremented"); // DEBUG
} }
timer = CHECK_SHARED_WAIT_TIME; timer = CHECK_SHARED_WAIT_TIME;
let info_result = get_info_from_shared(shared_data.clone(), false); let dirty_flag = atomic_dirty_flag.load(Ordering::Relaxed);
if let Ok(info) = info_result { if dirty_flag || check_due_to_track_timer_count < CHECK_TRACK_TIMER_MAX_COUNT {
if info.filename != filename { if dirty_flag {
filename = info.filename; atomic_dirty_flag.store(false, Ordering::Relaxed);
art_texture = None;
filename_font_size = None;
title.clear();
title_dim_opt = None;
artist.clear();
artist_dim_opt = None;
art_draw_params = None;
check_due_to_track_timer_count = 0;
} }
let duration_since = info.instant_rec.elapsed(); let info_result = get_info_from_shared(shared_data.clone());
let recorded_time = info.length - info.pos - duration_since.as_secs_f64(); if let Ok(info) = info_result {
if (recorded_time - track_timer).abs() > TIME_MAX_DIFF { if info.filename != filename {
track_timer = info.length - info.pos - duration_since.as_secs_f64(); filename = info.filename;
} art_texture = None;
if !info.error_text.is_empty() { filename_font_size = None;
error_text = info.error_text; title.clear();
} title_dim_opt = None;
if !info.title.is_empty() { artist.clear();
title = info.title; artist_dim_opt = None;
} art_draw_params = None;
if !info.artist.is_empty() { check_due_to_track_timer_count = 0;
artist = info.artist; }
let duration_since = info.instant_rec.elapsed();
let recorded_time = info.length - info.pos - duration_since.as_secs_f64();
if (recorded_time - track_timer).abs() > TIME_MAX_DIFF {
track_timer = info.length - info.pos - duration_since.as_secs_f64();
}
if !info.error_text.is_empty() {
error_text = info.error_text;
}
if !info.title.is_empty() {
title = info.title;
}
if !info.artist.is_empty() {
artist = info.artist;
}
} }
} }