From cd6e14814325d4d474c39e9ff6314cb26b2a2db7 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Fri, 17 Apr 2020 18:27:26 +0200 Subject: [PATCH] anvil: restore correct dispatching of wayland clients --- anvil/src/main.rs | 43 +++++++++++++++++++++++++------------- anvil/src/udev.rs | 35 +++++++++++++++---------------- anvil/src/winit.rs | 51 +++++++++++++++++++++++----------------------- 3 files changed, 71 insertions(+), 58 deletions(-) diff --git a/anvil/src/main.rs b/anvil/src/main.rs index 6b23038..7ba7dcf 100644 --- a/anvil/src/main.rs +++ b/anvil/src/main.rs @@ -7,6 +7,15 @@ extern crate slog; #[macro_use(define_roles)] extern crate smithay; +use std::{ + cell::RefCell, + rc::Rc, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; + use slog::Drain; use smithay::reexports::{ calloop::{generic::Generic, mio::Interest, EventLoop}, @@ -34,15 +43,13 @@ static POSSIBLE_BACKENDS: &[&str] = &[ ]; pub struct AnvilState { - pub need_wayland_dispatch: bool, - pub running: bool, + pub running: Arc, } impl Default for AnvilState { fn default() -> AnvilState { AnvilState { - need_wayland_dispatch: false, - running: true, + running: Arc::new(AtomicBool::new(true)), } } } @@ -54,25 +61,33 @@ fn main() { o!(), ); - let mut event_loop = EventLoop::::new().unwrap(); - let mut display = Display::new(); + let event_loop = EventLoop::::new().unwrap(); + let display = Rc::new(RefCell::new(Display::new())); // Glue for event dispatching - let mut wayland_event_source = Generic::from_raw_fd(display.get_poll_fd()); + let mut wayland_event_source = Generic::from_raw_fd(display.borrow().get_poll_fd()); wayland_event_source.set_interest(Interest::READABLE); - let _wayland_source = - event_loop - .handle() - .insert_source(wayland_event_source, |_, state: &mut AnvilState| { - state.need_wayland_dispatch = true; - }); + let _wayland_source = event_loop.handle().insert_source(wayland_event_source, { + let display = display.clone(); + let log = log.clone(); + move |_, state: &mut AnvilState| { + let mut display = display.borrow_mut(); + match display.dispatch(std::time::Duration::from_millis(0), state) { + Ok(_) => {} + Err(e) => { + error!(log, "I/O error on the Wayland display: {}", e); + state.running.store(false, Ordering::SeqCst); + } + } + } + }); let arg = ::std::env::args().nth(1); match arg.as_ref().map(|s| &s[..]) { #[cfg(feature = "winit")] Some("--winit") => { info!(log, "Starting anvil with winit backend"); - if let Err(()) = winit::run_winit(&mut display, &mut event_loop, log.clone()) { + if let Err(()) = winit::run_winit(display, event_loop, log.clone()) { crit!(log, "Failed to initialize winit backend."); } } diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index a83cd1b..b6fd370 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -5,10 +5,7 @@ use std::{ os::unix::io::{AsRawFd, RawFd}, path::PathBuf, rc::Rc, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, Mutex, - }, + sync::{atomic::Ordering, Arc, Mutex}, }; use glium::Surface as GliumSurface; @@ -85,8 +82,17 @@ type RenderDevice = EglDevice< type RenderSurface = EglSurface, LegacyDrmDevice>>>; -pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log: Logger) -> Result<(), ()> { - let name = display.add_socket_auto().unwrap().into_string().unwrap(); +pub fn run_udev( + display: Rc>, + mut event_loop: EventLoop, + log: Logger, +) -> Result<(), ()> { + let name = display + .borrow_mut() + .add_socket_auto() + .unwrap() + .into_string() + .unwrap(); info!(log, "Listening on wayland socket"; "name" => name.clone()); ::std::env::set_var("WAYLAND_DISPLAY", name); @@ -98,8 +104,6 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log #[cfg(not(feature = "egl"))] let buffer_utils = BufferUtils::new(log.clone()); - let display = Rc::new(RefCell::new(display)); - /* * Initialize the compositor */ @@ -115,7 +119,7 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log let (udev_observer, udev_notifier) = notify_multiplexer(); let udev_session_id = notifier.register(udev_observer); - let running = Arc::new(AtomicBool::new(true)); + let mut state = AnvilState::default(); let pointer_location = Rc::new(RefCell::new((0.0, 0.0))); let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default)); @@ -237,7 +241,7 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log keyboard, window_map.clone(), (w, h), - running.clone(), + state.running.clone(), pointer_location, session, )); @@ -258,21 +262,14 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log /* * And run our loop */ - let mut state = AnvilState::default(); - while running.load(Ordering::SeqCst) { + while state.running.load(Ordering::SeqCst) { if event_loop .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state) .is_err() { - running.store(false, Ordering::SeqCst); + state.running.store(false, Ordering::SeqCst); } else { - if state.need_wayland_dispatch { - display - .borrow_mut() - .dispatch(std::time::Duration::from_millis(0), &mut state) - .unwrap(); - } display.borrow_mut().flush_clients(&mut state); window_map.borrow_mut().refresh(); } diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index 19c7a9b..8b48a3f 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -1,10 +1,7 @@ use std::{ cell::RefCell, rc::Rc, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, Mutex, - }, + sync::{atomic::Ordering, Arc, Mutex}, }; use smithay::{ @@ -30,15 +27,15 @@ use crate::shell::init_shell; use crate::AnvilState; pub fn run_winit( - display: &mut Display, - event_loop: &mut EventLoop, + display: Rc>, + mut event_loop: EventLoop, log: Logger, ) -> Result<(), ()> { let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?; #[cfg(feature = "egl")] let egl_buffer_reader = Rc::new(RefCell::new( - if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display) { + if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) { info!(log, "EGL hardware-acceleration enabled"); Some(egl_buffer_reader) } else { @@ -57,25 +54,31 @@ pub fn run_winit( #[cfg(not(feature = "egl"))] let buffer_utils = BufferUtils::new(log.clone()); - let name = display.add_socket_auto().unwrap().into_string().unwrap(); + let name = display + .borrow_mut() + .add_socket_auto() + .unwrap() + .into_string() + .unwrap(); info!(log, "Listening on wayland socket"; "name" => name.clone()); ::std::env::set_var("WAYLAND_DISPLAY", name); - let running = Arc::new(AtomicBool::new(true)); + let mut state = AnvilState::default(); /* * Initialize the globals */ - init_shm_global(display, vec![], log.clone()); + init_shm_global(&mut display.borrow_mut(), vec![], log.clone()); - let (compositor_token, _, _, window_map) = init_shell(display, buffer_utils, log.clone()); + let (compositor_token, _, _, window_map) = + init_shell(&mut display.borrow_mut(), buffer_utils, log.clone()); let dnd_icon = Arc::new(Mutex::new(None)); let dnd_icon2 = dnd_icon.clone(); init_data_device( - display, + &mut display.borrow_mut(), move |event| match event { DataDeviceEvent::DnDStarted { icon, .. } => { *dnd_icon2.lock().unwrap() = icon; @@ -90,7 +93,12 @@ pub fn run_winit( log.clone(), ); - let (mut seat, _) = Seat::new(display, "winit".into(), compositor_token, log.clone()); + let (mut seat, _) = Seat::new( + &mut display.borrow_mut(), + "winit".into(), + compositor_token, + log.clone(), + ); let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default)); @@ -107,7 +115,7 @@ pub fn run_winit( .expect("Failed to initialize the keyboard"); let (output, _) = Output::new( - display, + &mut display.borrow_mut(), "Winit".into(), PhysicalProperties { width: 0, @@ -142,13 +150,13 @@ pub fn run_winit( keyboard, window_map.clone(), (0, 0), - running.clone(), + state.running.clone(), pointer_location.clone(), )); info!(log, "Initialization completed, starting the main loop."); - while running.load(Ordering::SeqCst) { + while state.running.load(Ordering::SeqCst) { input.dispatch_new_events().unwrap(); // drawing logic @@ -192,20 +200,13 @@ pub fn run_winit( } } - let mut state = AnvilState::default(); - if event_loop .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state) .is_err() { - running.store(false, Ordering::SeqCst); + state.running.store(false, Ordering::SeqCst); } else { - if state.need_wayland_dispatch { - display - .dispatch(std::time::Duration::from_millis(0), &mut state) - .unwrap(); - } - display.flush_clients(&mut state); + display.borrow_mut().flush_clients(&mut state); window_map.borrow_mut().refresh(); } }