Update calloop to 0.6

This commit is contained in:
Victor Berger 2020-04-25 19:10:02 +02:00 committed by Victor Berger
parent eddbe3c708
commit b3aae074e4
10 changed files with 106 additions and 107 deletions

View File

@ -12,7 +12,7 @@ members = [ "anvil" ]
[dependencies] [dependencies]
bitflags = "1" bitflags = "1"
calloop = "0.5.1" calloop = "0.6.2"
dbus = { version = "0.8", optional = true } dbus = { version = "0.8", optional = true }
drm = { version = "^0.4.0", git = "https://github.com/drakulix/drm-rs", branch = "develop", optional = true } drm = { version = "^0.4.0", git = "https://github.com/drakulix/drm-rs", branch = "develop", optional = true }
gbm = { version = "^0.6.0", git = "https://github.com/drakulix/gbm.rs", branch = "develop", optional = true, default-features = false, features = ["drm-support"] } gbm = { version = "^0.6.0", git = "https://github.com/drakulix/gbm.rs", branch = "develop", optional = true, default-features = false, features = ["drm-support"] }

View File

@ -10,9 +10,8 @@ use std::{
use smithay::{ use smithay::{
reexports::{ reexports::{
calloop::{ calloop::{
generic::{Generic, SourceRawFd}, generic::{Fd, Generic},
mio::Interest, Interest, LoopHandle, Mode, Source,
LoopHandle, Source,
}, },
wayland_server::{protocol::wl_surface::WlSurface, Display}, wayland_server::{protocol::wl_surface::WlSurface, Display},
}, },
@ -35,7 +34,7 @@ pub struct AnvilState {
pub dnd_icon: Arc<Mutex<Option<WlSurface>>>, pub dnd_icon: Arc<Mutex<Option<WlSurface>>>,
pub log: slog::Logger, pub log: slog::Logger,
// things we must keep alive // things we must keep alive
_wayland_event_source: Source<Generic<SourceRawFd>>, _wayland_event_source: Source<Generic<Fd>>,
} }
impl AnvilState { impl AnvilState {
@ -48,21 +47,18 @@ impl AnvilState {
// init the wayland connection // init the wayland connection
let _wayland_event_source = handle let _wayland_event_source = handle
.insert_source( .insert_source(
{ Generic::from_fd(display.borrow().get_poll_fd(), Interest::Readable, Mode::Level),
let mut source = Generic::from_raw_fd(display.borrow().get_poll_fd());
source.set_interest(Interest::READABLE);
source
},
{ {
let display = display.clone(); let display = display.clone();
let log = log.clone(); let log = log.clone();
move |_, state: &mut AnvilState| { move |_, _, state: &mut AnvilState| {
let mut display = display.borrow_mut(); let mut display = display.borrow_mut();
match display.dispatch(std::time::Duration::from_millis(0), state) { match display.dispatch(std::time::Duration::from_millis(0), state) {
Ok(_) => {} Ok(_) => Ok(()),
Err(e) => { Err(e) => {
error!(log, "I/O error on the Wayland display: {}", e); error!(log, "I/O error on the Wayland display: {}", e);
state.running.store(false, Ordering::SeqCst); state.running.store(false, Ordering::SeqCst);
Err(e)
} }
} }
} }

View File

@ -35,10 +35,7 @@ use smithay::{
udev::{primary_gpu, udev_backend_bind, UdevBackend, UdevHandler}, udev::{primary_gpu, udev_backend_bind, UdevBackend, UdevHandler},
}, },
reexports::{ reexports::{
calloop::{ calloop::{generic::Generic, EventLoop, LoopHandle, Source},
generic::{Generic, SourceFd},
EventLoop, LoopHandle, Source,
},
drm::control::{ drm::control::{
connector::{Info as ConnectorInfo, State as ConnectorState}, connector::{Info as ConnectorInfo, State as ConnectorState},
crtc, crtc,
@ -226,7 +223,7 @@ pub fn run_udev(
let libinput_event_source = libinput_bind(libinput_backend, event_loop.handle()) let libinput_event_source = libinput_bind(libinput_backend, event_loop.handle())
.map_err(|e| -> IoError { e.into() }) .map_err(|e| -> IoError { e.into() })
.unwrap(); .unwrap();
let session_event_source = auto_session_bind(notifier, &event_loop.handle()) let session_event_source = auto_session_bind(notifier, event_loop.handle())
.map_err(|(e, _)| e) .map_err(|(e, _)| e)
.unwrap(); .unwrap();
let udev_event_source = udev_backend_bind(udev_backend, &event_loop.handle()) let udev_event_source = udev_backend_bind(udev_backend, &event_loop.handle())
@ -256,15 +253,15 @@ pub fn run_udev(
notifier.unregister(libinput_session_id); notifier.unregister(libinput_session_id);
notifier.unregister(udev_session_id); notifier.unregister(udev_session_id);
libinput_event_source.remove(); event_loop.handle().remove(libinput_event_source);
udev_event_source.remove(); event_loop.handle().remove(udev_event_source);
Ok(()) Ok(())
} }
struct BackendData<S: SessionNotifier> { struct BackendData<S: SessionNotifier> {
id: S::Id, id: S::Id,
event_source: Source<Generic<SourceFd<RenderDevice>>>, event_source: Source<Generic<RenderDevice>>,
surfaces: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>, surfaces: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>,
} }
@ -482,24 +479,27 @@ impl<S: SessionNotifier, Data: 'static> UdevHandler for UdevHandlerImpl<S, Data>
fn device_changed(&mut self, device: dev_t) { fn device_changed(&mut self, device: dev_t) {
//quick and dirty, just re-init all backends //quick and dirty, just re-init all backends
if let Some(ref mut backend_data) = self.backends.get_mut(&device) { if let Some(ref mut backend_data) = self.backends.get_mut(&device) {
let source = backend_data.event_source.clone_inner(); let logger = &self.logger;
let mut evented = source.borrow_mut(); let pointer_image = &self.pointer_image;
let egl_buffer_reader = self.egl_buffer_reader.clone();
self.loop_handle
.with_source(&backend_data.event_source, |source| {
let mut backends = backend_data.surfaces.borrow_mut(); let mut backends = backend_data.surfaces.borrow_mut();
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
let new_backends = UdevHandlerImpl::<S, Data>::scan_connectors( let new_backends = UdevHandlerImpl::<S, Data>::scan_connectors(
&mut (*evented).0, &mut source.file,
self.egl_buffer_reader.clone(), egl_buffer_reader,
&self.logger, logger,
); );
#[cfg(not(feature = "egl"))] #[cfg(not(feature = "egl"))]
let new_backends = UdevHandlerImpl::<S, Data>::scan_connectors(&mut (*evented).0, &self.logger); let new_backends = UdevHandlerImpl::<S, Data>::scan_connectors(&mut source.file, logger);
*backends = new_backends; *backends = new_backends;
for renderer in backends.values() { for renderer in backends.values() {
// create cursor // create cursor
renderer renderer
.borrow() .borrow()
.set_cursor_representation(&self.pointer_image, (2, 2)) .set_cursor_representation(pointer_image, (2, 2))
.unwrap(); .unwrap();
// render first frame // render first frame
@ -509,6 +509,7 @@ impl<S: SessionNotifier, Data: 'static> UdevHandler for UdevHandlerImpl<S, Data>
frame.finish().unwrap(); frame.finish().unwrap();
} }
} }
});
} }
} }
@ -519,11 +520,7 @@ impl<S: SessionNotifier, Data: 'static> UdevHandler for UdevHandlerImpl<S, Data>
backend_data.surfaces.borrow_mut().clear(); backend_data.surfaces.borrow_mut().clear();
debug!(self.logger, "Surfaces dropped"); debug!(self.logger, "Surfaces dropped");
let device = Rc::try_unwrap(backend_data.event_source.remove().unwrap()) let device = self.loop_handle.remove(backend_data.event_source).unwrap();
.map_err(|_| "This should not happend")
.unwrap()
.into_inner()
.0;
// don't use hardware acceleration anymore, if this was the primary gpu // don't use hardware acceleration anymore, if this was the primary gpu
#[cfg(feature = "egl")] #[cfg(feature = "egl")]

View File

@ -46,10 +46,7 @@ use std::iter::IntoIterator;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::path::PathBuf; use std::path::PathBuf;
use calloop::generic::{Generic, SourceFd}; use calloop::{generic::Generic, InsertError, LoopHandle, Source};
use calloop::mio::Interest;
use calloop::InsertError;
use calloop::{LoopHandle, Source};
use super::graphics::SwapBuffersError; use super::graphics::SwapBuffersError;
@ -245,7 +242,7 @@ impl<A: AsRawFd> DevPath for A {
} }
/// calloop source associated with a Device /// calloop source associated with a Device
pub type DrmSource<D> = Generic<SourceFd<D>>; pub type DrmSource<D> = Generic<D>;
/// Bind a `Device` to an [`EventLoop`](calloop::EventLoop), /// Bind a `Device` to an [`EventLoop`](calloop::EventLoop),
/// ///
@ -259,10 +256,10 @@ where
D: Device, D: Device,
Data: 'static, Data: 'static,
{ {
let mut source = Generic::from_fd_source(device); let source = Generic::new(device, calloop::Interest::Readable, calloop::Mode::Level);
source.set_interest(Interest::READABLE);
handle.insert_source(source, |evt, _| { handle.insert_source(source, |_, source, _| {
evt.source.borrow_mut().0.process_events(); source.process_events();
Ok(())
}) })
} }

View File

@ -17,11 +17,7 @@ use std::{
os::unix::io::{AsRawFd, RawFd}, os::unix::io::{AsRawFd, RawFd},
}; };
use calloop::{ use calloop::{generic::Generic, InsertError, LoopHandle, Source};
generic::{Generic, SourceFd},
mio::Interest,
InsertError, LoopHandle, Source,
};
// No idea if this is the same across unix platforms // No idea if this is the same across unix platforms
// Lets make this linux exclusive for now, once someone tries to build it for // Lets make this linux exclusive for now, once someone tries to build it for
@ -426,7 +422,7 @@ impl AsRawFd for LibinputInputBackend {
} }
/// calloop source associated with the libinput backend /// calloop source associated with the libinput backend
pub type LibinputSource = Generic<SourceFd<LibinputInputBackend>>; pub type LibinputSource = Generic<LibinputInputBackend>;
/// Binds a [`LibinputInputBackend`] to a given [`LoopHandle`]. /// Binds a [`LibinputInputBackend`] to a given [`LoopHandle`].
/// ///
@ -436,13 +432,13 @@ pub fn libinput_bind<Data: 'static>(
backend: LibinputInputBackend, backend: LibinputInputBackend,
handle: LoopHandle<Data>, handle: LoopHandle<Data>,
) -> Result<Source<LibinputSource>, InsertError<LibinputSource>> { ) -> Result<Source<LibinputSource>, InsertError<LibinputSource>> {
let mut source = Generic::from_fd_source(backend); let source = Generic::new(backend, calloop::Interest::Readable, calloop::Mode::Level);
source.set_interest(Interest::READABLE);
handle.insert_source(source, move |evt, _| { handle.insert_source(source, move |_, backend, _| {
let mut backend = evt.source.borrow_mut(); if let Err(error) = backend.dispatch_new_events() {
if let Err(error) = backend.0.dispatch_new_events() { warn!(backend.logger, "Libinput errored: {}", error);
warn!(backend.0.logger, "Libinput errored: {}", error); return Err(std::io::Error::new(std::io::ErrorKind::Other, Box::new(error)));
} }
Ok(())
}) })
} }

View File

@ -146,7 +146,7 @@ impl AutoSession {
/// session state and call its [`SessionObserver`]s. /// session state and call its [`SessionObserver`]s.
pub fn auto_session_bind<Data: 'static>( pub fn auto_session_bind<Data: 'static>(
notifier: AutoSessionNotifier, notifier: AutoSessionNotifier,
handle: &LoopHandle<Data>, handle: LoopHandle<Data>,
) -> ::std::result::Result<BoundAutoSession, (IoError, AutoSessionNotifier)> { ) -> ::std::result::Result<BoundAutoSession, (IoError, AutoSessionNotifier)> {
Ok(match notifier { Ok(match notifier {
#[cfg(feature = "backend_session_logind")] #[cfg(feature = "backend_session_logind")]

View File

@ -53,9 +53,8 @@ use std::{
use systemd::login; use systemd::login;
use calloop::{ use calloop::{
generic::{Event, Generic, SourceRawFd}, generic::{Fd, Generic},
mio::Interest, InsertError, Interest, LoopHandle, Readiness, Source,
InsertError, LoopHandle, Source,
}; };
struct LogindSessionImpl { struct LogindSessionImpl {
@ -433,7 +432,8 @@ impl SessionNotifier for LogindSessionNotifier {
pub struct BoundLogindSession { pub struct BoundLogindSession {
notifier: LogindSessionNotifier, notifier: LogindSessionNotifier,
_watches: Vec<Watch>, _watches: Vec<Watch>,
sources: Vec<Source<Generic<SourceRawFd>>>, sources: Vec<Source<Generic<Fd>>>,
kill_source: Box<dyn Fn(Source<Generic<Fd>>)>,
} }
/// Bind a [`LogindSessionNotifier`] to an [`EventLoop`](calloop::EventLoop). /// Bind a [`LogindSessionNotifier`] to an [`EventLoop`](calloop::EventLoop).
@ -443,7 +443,7 @@ pub struct BoundLogindSession {
/// session state and call it's [`SessionObserver`]s. /// session state and call it's [`SessionObserver`]s.
pub fn logind_session_bind<Data: 'static>( pub fn logind_session_bind<Data: 'static>(
notifier: LogindSessionNotifier, notifier: LogindSessionNotifier,
handle: &LoopHandle<Data>, handle: LoopHandle<Data>,
) -> ::std::result::Result<BoundLogindSession, (IoError, LogindSessionNotifier)> { ) -> ::std::result::Result<BoundLogindSession, (IoError, LogindSessionNotifier)> {
let watches = notifier.internal.conn.borrow().watch_fds(); let watches = notifier.internal.conn.borrow().watch_fds();
@ -453,19 +453,22 @@ pub fn logind_session_bind<Data: 'static>(
.into_iter() .into_iter()
.filter_map(|watch| { .filter_map(|watch| {
let interest = match (watch.writable(), watch.readable()) { let interest = match (watch.writable(), watch.readable()) {
(true, true) => Interest::WRITABLE | Interest::READABLE, (true, true) => Interest::Both,
(true, false) => Interest::WRITABLE, (true, false) => Interest::Writable,
(false, true) => Interest::READABLE, (false, true) => Interest::Readable,
(false, false) => return None (false, false) => return None,
}; };
let mut source = Generic::from_raw_fd(watch.fd()); let source = Generic::from_fd(watch.fd(), interest, calloop::Mode::Level);
source.set_interest(interest);
let source = handle.insert_source(source, { let source = handle.insert_source(source, {
let mut notifier = notifier.clone(); let mut notifier = notifier.clone();
move |evt, _| notifier.event(evt) move |readiness, fd, _| {
notifier.event(readiness, fd.0);
Ok(())
}
}); });
Some(source) Some(source)
}).collect::<::std::result::Result<Vec<Source<Generic<SourceRawFd>>>, InsertError<Generic<SourceRawFd>>>>() })
.collect::<::std::result::Result<Vec<Source<Generic<Fd>>>, InsertError<Generic<Fd>>>>()
.map_err(|err| { .map_err(|err| {
( (
err.into(), err.into(),
@ -479,6 +482,7 @@ pub fn logind_session_bind<Data: 'static>(
notifier, notifier,
_watches: watches, _watches: watches,
sources, sources,
kill_source: Box::new(move |source| handle.kill(source)),
}) })
} }
@ -486,7 +490,7 @@ impl BoundLogindSession {
/// Unbind the logind session from the [`EventLoop`](calloop::EventLoop) /// Unbind the logind session from the [`EventLoop`](calloop::EventLoop)
pub fn unbind(self) -> LogindSessionNotifier { pub fn unbind(self) -> LogindSessionNotifier {
for source in self.sources { for source in self.sources {
source.remove(); (self.kill_source)(source);
} }
self.notifier self.notifier
} }
@ -508,9 +512,7 @@ impl Drop for LogindSessionNotifier {
} }
impl LogindSessionNotifier { impl LogindSessionNotifier {
fn event(&mut self, event: Event<SourceRawFd>) { fn event(&mut self, readiness: Readiness, fd: RawFd) {
let fd = event.source.borrow().0;
let readiness = event.readiness;
let conn = self.internal.conn.borrow(); let conn = self.internal.conn.borrow();
let items = conn.watch_handle( let items = conn.watch_handle(
fd, fd,

View File

@ -396,13 +396,18 @@ impl DirectSessionNotifier {
pub struct BoundDirectSession { pub struct BoundDirectSession {
source: Source<Signals>, source: Source<Signals>,
notifier: Rc<RefCell<DirectSessionNotifier>>, notifier: Rc<RefCell<DirectSessionNotifier>>,
kill_source: Box<dyn Fn(Source<Signals>)>,
} }
impl BoundDirectSession { impl BoundDirectSession {
/// Unbind the direct session from the [`EventLoop`](calloop::EventLoop) /// Unbind the direct session from the [`EventLoop`](calloop::EventLoop)
pub fn unbind(self) -> DirectSessionNotifier { pub fn unbind(self) -> DirectSessionNotifier {
let BoundDirectSession { source, notifier } = self; let BoundDirectSession {
source.remove(); source,
notifier,
kill_source,
} = self;
kill_source(source);
Rc::try_unwrap(notifier) Rc::try_unwrap(notifier)
.map(RefCell::into_inner) .map(RefCell::into_inner)
.unwrap_or_else(|_| panic!("Notifier should have been freed from the event loop!")) .unwrap_or_else(|_| panic!("Notifier should have been freed from the event loop!"))
@ -416,7 +421,7 @@ impl BoundDirectSession {
/// session state and call it's [`SessionObserver`]s. /// session state and call it's [`SessionObserver`]s.
pub fn direct_session_bind<Data: 'static>( pub fn direct_session_bind<Data: 'static>(
notifier: DirectSessionNotifier, notifier: DirectSessionNotifier,
handle: &LoopHandle<Data>, handle: LoopHandle<Data>,
) -> ::std::result::Result<BoundDirectSession, (IoError, DirectSessionNotifier)> { ) -> ::std::result::Result<BoundDirectSession, (IoError, DirectSessionNotifier)> {
let signal = notifier.signal; let signal = notifier.signal;
let source = match Signals::new(&[signal]) { let source = match Signals::new(&[signal]) {
@ -428,7 +433,7 @@ pub fn direct_session_bind<Data: 'static>(
let source = handle let source = handle
.insert_source(source, { .insert_source(source, {
let notifier = notifier.clone(); let notifier = notifier.clone();
move |_, _| notifier.borrow_mut().signal_received() move |_, _, _| notifier.borrow_mut().signal_received()
}) })
.map_err(move |e| { .map_err(move |e| {
// the backend in the closure should already have been dropped // the backend in the closure should already have been dropped
@ -437,7 +442,12 @@ pub fn direct_session_bind<Data: 'static>(
.into_inner(); .into_inner();
(e.into(), notifier) (e.into(), notifier)
})?; })?;
Ok(BoundDirectSession { source, notifier }) let kill_source = Box::new(move |source| handle.kill(source));
Ok(BoundDirectSession {
source,
notifier,
kill_source,
})
} }
/// Errors related to direct/tty sessions /// Errors related to direct/tty sessions

View File

@ -19,11 +19,7 @@ use std::{
}; };
use udev::{Enumerator, EventType, MonitorBuilder, MonitorSocket}; use udev::{Enumerator, EventType, MonitorBuilder, MonitorSocket};
use calloop::{ use calloop::{generic::Generic, InsertError, LoopHandle, Source};
generic::{Generic, SourceFd},
mio::Interest,
InsertError, LoopHandle, Source,
};
/// Backend to monitor available drm devices. /// Backend to monitor available drm devices.
/// ///
@ -91,7 +87,7 @@ impl<T: UdevHandler + 'static> Drop for UdevBackend<T> {
} }
/// calloop event source associated with the Udev backend /// calloop event source associated with the Udev backend
pub type UdevSource<T> = Generic<SourceFd<UdevBackend<T>>>; pub type UdevSource<T> = Generic<UdevBackend<T>>;
/// Binds a [`UdevBackend`] to a given [`EventLoop`](calloop::EventLoop). /// Binds a [`UdevBackend`] to a given [`EventLoop`](calloop::EventLoop).
/// ///
@ -101,11 +97,11 @@ pub fn udev_backend_bind<T: UdevHandler + 'static, Data: 'static>(
udev: UdevBackend<T>, udev: UdevBackend<T>,
handle: &LoopHandle<Data>, handle: &LoopHandle<Data>,
) -> Result<Source<UdevSource<T>>, InsertError<UdevSource<T>>> { ) -> Result<Source<UdevSource<T>>, InsertError<UdevSource<T>>> {
let mut source = Generic::from_fd_source(udev); let source = Generic::new(udev, calloop::Interest::Readable, calloop::Mode::Level);
source.set_interest(Interest::READABLE);
handle.insert_source(source, |evt, _| { handle.insert_source(source, |_, backend, _| {
evt.source.borrow_mut().0.process_events(); backend.process_events();
Ok(())
}) })
} }

View File

@ -91,11 +91,15 @@ impl<WM: XWindowManager + 'static> XWayland<WM> {
let log = crate::slog_or_stdlog(logger); let log = crate::slog_or_stdlog(logger);
let inner = Rc::new(RefCell::new(Inner { let inner = Rc::new(RefCell::new(Inner {
wm, wm,
kill_source: {
let handle = handle.clone();
Box::new(move |source| handle.kill(source))
},
source_maker: Box::new(move |inner| { source_maker: Box::new(move |inner| {
handle handle
.insert_source( .insert_source(
Signals::new(&[Signal::SIGUSR1]).map_err(|_| ())?, Signals::new(&[Signal::SIGUSR1]).map_err(|_| ())?,
move |evt, _| { move |evt, _, _| {
debug_assert!(evt.signal() == Signal::SIGUSR1); debug_assert!(evt.signal() == Signal::SIGUSR1);
xwayland_ready(&inner); xwayland_ready(&inner);
}, },
@ -134,6 +138,7 @@ struct Inner<WM: XWindowManager> {
source_maker: Box<SourceMaker<WM>>, source_maker: Box<SourceMaker<WM>>,
wayland_display: Rc<RefCell<Display>>, wayland_display: Rc<RefCell<Display>>,
instance: Option<XWaylandInstance>, instance: Option<XWaylandInstance>,
kill_source: Box<dyn Fn(Source<Signals>)>,
log: ::slog::Logger, log: ::slog::Logger,
} }
@ -252,7 +257,7 @@ impl<WM: XWindowManager> Inner<WM> {
instance.wayland_client.kill(); instance.wayland_client.kill();
// remove the event source // remove the event source
if let Some(s) = instance.sigusr1_handler.take() { if let Some(s) = instance.sigusr1_handler.take() {
s.remove(); (self.kill_source)(s);
} }
// All connections and lockfiles are cleaned by their destructors // All connections and lockfiles are cleaned by their destructors
@ -336,7 +341,7 @@ fn xwayland_ready<WM: XWindowManager>(inner: &Rc<RefCell<Inner<WM>>>) {
// in all cases, cleanup // in all cases, cleanup
if let Some(s) = instance.sigusr1_handler.take() { if let Some(s) = instance.sigusr1_handler.take() {
s.remove(); (inner.kill_source)(s);
} }
} }