From 7e00ec5f9adf148481d91f15cd931b3fe69a33d4 Mon Sep 17 00:00:00 2001 From: FractalFir Date: Tue, 8 Oct 2024 16:47:17 +0200 Subject: [PATCH] fix(Wayland): Fix multithreading bug + fix segfault in libdubs on certain systems. (#156) * Added a multithreading test for Wayland. Fixed a bug which caused screnshots to fail when two threads tried to take them at once. * Fixed a segfault in lbdbus modified: Cargo.toml modified: src/linux/wayland_capture.rs --- Cargo.toml | 2 +- src/linux/wayland_capture.rs | 33 ++++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b32a718..94fabdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ windows = { version = "0.58", features = [ [target.'cfg(target_os="linux")'.dependencies] percent-encoding = "2.3" xcb = { version = "1.4", features = ["randr"] } -dbus = { version = "0.9", features = ["vendored"] } +dbus = { version = "0.9.7" } [dev-dependencies] fs_extra = "1.3" diff --git a/src/linux/wayland_capture.rs b/src/linux/wayland_capture.rs index 7522fa3..6b5823c 100644 --- a/src/linux/wayland_capture.rs +++ b/src/linux/wayland_capture.rs @@ -43,7 +43,7 @@ impl SignalArgs for OrgFreedesktopPortalRequestResponse { const NAME: &'static str = "Response"; const INTERFACE: &'static str = "org.freedesktop.portal.Request"; } - +static DBUS_LOCK: Mutex<()> = Mutex::new(()); fn org_gnome_shell_screenshot( conn: &Connection, x: i32, @@ -172,9 +172,32 @@ pub fn wayland_capture(impl_monitor: &ImplMonitor) -> XCapResult { let y = ((impl_monitor.y as f32) * impl_monitor.scale_factor) as i32; let width = ((impl_monitor.width as f32) * impl_monitor.scale_factor) as i32; let height = ((impl_monitor.height as f32) * impl_monitor.scale_factor) as i32; - + let lock = DBUS_LOCK.lock(); let conn = Connection::new_session()?; - - org_gnome_shell_screenshot(&conn, x, y, width, height) - .or_else(|_| org_freedesktop_portal_screenshot(&conn, x, y, width, height)) + let res = org_gnome_shell_screenshot(&conn, x, y, width, height) + .or_else(|_| org_freedesktop_portal_screenshot(&conn, x, y, width, height)); + drop(lock); + res +} +#[test] +fn screnshot_multithreaded() { + fn make_screenshots() { + let monitors = crate::monitor::Monitor::all().unwrap(); + for monitor in monitors { + monitor.capture_image().unwrap(); + } + } + // Try making screenshots in paralel. If this times out, then this means that there is a threading issue. + const PARALELISM: usize = 10; + let handles: Vec<_> = (0..PARALELISM) + .map(|_| { + std::thread::spawn(|| { + make_screenshots(); + }) + }) + .collect(); + make_screenshots(); + handles + .into_iter() + .for_each(|handle| handle.join().unwrap()); }