diff --git a/daemon/src/wallpaper.rs b/daemon/src/wallpaper.rs index 5c140a70..ea8ff79f 100644 --- a/daemon/src/wallpaper.rs +++ b/daemon/src/wallpaper.rs @@ -4,7 +4,7 @@ use std::{ num::NonZeroI32, sync::{ atomic::{AtomicBool, AtomicUsize, Ordering}, - Arc, Mutex, MutexGuard, + Arc, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard, }, }; @@ -55,7 +55,7 @@ struct WallpaperInner { pub struct Wallpaper { output_id: u32, - inner: Mutex, + inner: RwLock, layer_surface: LayerSurface, animation_state: AnimationState, @@ -108,7 +108,7 @@ impl Wallpaper { output_id: output_info.id, layer_surface, pool, - inner: Mutex::new(WallpaperInner { + inner: RwLock::new(WallpaperInner { width, height, scale_factor, @@ -149,8 +149,13 @@ impl Wallpaper { } #[inline] - fn lock(&self) -> (MutexGuard, MutexGuard) { - (self.inner.lock().unwrap(), self.pool.lock().unwrap()) + fn lock(&self) -> (RwLockReadGuard, MutexGuard) { + (self.inner.read().unwrap(), self.pool.lock().unwrap()) + } + + #[inline] + fn lock_inner_mut(&self) -> (RwLockWriteGuard, MutexGuard) { + (self.inner.write().unwrap(), self.pool.lock().unwrap()) } pub fn canvas_change(&self, f: F) -> T @@ -158,10 +163,12 @@ impl Wallpaper { F: FnOnce(&mut [u8]) -> T, { loop { - let (inner, mut pool) = self.lock(); - if let Some(canvas) = inner.slot.canvas(&mut pool) { - log::debug!("got canvas! - output {}", self.output_id); - return f(canvas); + { + let (inner, mut pool) = self.lock(); + if let Some(canvas) = inner.slot.canvas(&mut pool) { + log::debug!("got canvas! - output {}", self.output_id); + return f(canvas); + } } log::debug!("failed to get canvas - output {}", self.output_id); // sleep to mitigate busy waiting @@ -204,7 +211,7 @@ impl Wallpaper { pub fn set_img_info(&self, img_info: BgImg) { log::debug!("output {} - drawing: {}", self.output_id, img_info); - self.lock().0.img = img_info; + self.lock_inner_mut().0.img = img_info; } pub fn draw(&self) { @@ -233,7 +240,7 @@ impl Wallpaper { if let Some(s) = scale_factor { self.layer_surface.set_buffer_scale(s.get() as u32).unwrap(); } - let (mut inner, mut pool) = self.lock(); + let (mut inner, mut pool) = self.lock_inner_mut(); let width = width.unwrap_or(inner.width); let height = height.unwrap_or(inner.height); let scale_factor = scale_factor.unwrap_or(inner.scale_factor); diff --git a/utils/src/ipc.rs b/utils/src/ipc.rs index 2cb77498..ff2c4c33 100644 --- a/utils/src/ipc.rs +++ b/utils/src/ipc.rs @@ -300,8 +300,20 @@ impl Answer { pub fn read_socket(stream: &UnixStream) -> Result, String> { let mut reader = BufReader::new(stream); let mut buf = vec![0; 8]; - if let Err(e) = reader.read_exact(&mut buf[0..std::mem::size_of::()]) { - return Err(format!("failed to read serialized length: {e}")); + + let mut tries = 0; + loop { + match reader.read_exact(&mut buf[0..std::mem::size_of::()]) { + Ok(()) => break, + Err(e) => { + if e.kind() == std::io::ErrorKind::WouldBlock && tries < 5 { + std::thread::sleep(Duration::from_millis(1)); + } else { + return Err(format!("failed to read serialized length: {e}")); + } + } + } + tries += 1; } let len = usize::from_ne_bytes(buf[0..std::mem::size_of::()].try_into().unwrap()); buf.clear();