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]
bitflags = "1"
calloop = "0.5.1"
calloop = "0.6.2"
dbus = { version = "0.8", 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"] }

View File

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

View File

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

View File

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

View File

@ -17,11 +17,7 @@ use std::{
os::unix::io::{AsRawFd, RawFd},
};
use calloop::{
generic::{Generic, SourceFd},
mio::Interest,
InsertError, LoopHandle, Source,
};
use calloop::{generic::Generic, InsertError, LoopHandle, Source};
// No idea if this is the same across unix platforms
// 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
pub type LibinputSource = Generic<SourceFd<LibinputInputBackend>>;
pub type LibinputSource = Generic<LibinputInputBackend>;
/// Binds a [`LibinputInputBackend`] to a given [`LoopHandle`].
///
@ -436,13 +432,13 @@ pub fn libinput_bind<Data: 'static>(
backend: LibinputInputBackend,
handle: LoopHandle<Data>,
) -> Result<Source<LibinputSource>, InsertError<LibinputSource>> {
let mut source = Generic::from_fd_source(backend);
source.set_interest(Interest::READABLE);
let source = Generic::new(backend, calloop::Interest::Readable, calloop::Mode::Level);
handle.insert_source(source, move |evt, _| {
let mut backend = evt.source.borrow_mut();
if let Err(error) = backend.0.dispatch_new_events() {
warn!(backend.0.logger, "Libinput errored: {}", error);
handle.insert_source(source, move |_, backend, _| {
if let Err(error) = backend.dispatch_new_events() {
warn!(backend.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.
pub fn auto_session_bind<Data: 'static>(
notifier: AutoSessionNotifier,
handle: &LoopHandle<Data>,
handle: LoopHandle<Data>,
) -> ::std::result::Result<BoundAutoSession, (IoError, AutoSessionNotifier)> {
Ok(match notifier {
#[cfg(feature = "backend_session_logind")]

View File

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

View File

@ -396,13 +396,18 @@ impl DirectSessionNotifier {
pub struct BoundDirectSession {
source: Source<Signals>,
notifier: Rc<RefCell<DirectSessionNotifier>>,
kill_source: Box<dyn Fn(Source<Signals>)>,
}
impl BoundDirectSession {
/// Unbind the direct session from the [`EventLoop`](calloop::EventLoop)
pub fn unbind(self) -> DirectSessionNotifier {
let BoundDirectSession { source, notifier } = self;
source.remove();
let BoundDirectSession {
source,
notifier,
kill_source,
} = self;
kill_source(source);
Rc::try_unwrap(notifier)
.map(RefCell::into_inner)
.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.
pub fn direct_session_bind<Data: 'static>(
notifier: DirectSessionNotifier,
handle: &LoopHandle<Data>,
handle: LoopHandle<Data>,
) -> ::std::result::Result<BoundDirectSession, (IoError, DirectSessionNotifier)> {
let signal = notifier.signal;
let source = match Signals::new(&[signal]) {
@ -428,7 +433,7 @@ pub fn direct_session_bind<Data: 'static>(
let source = handle
.insert_source(source, {
let notifier = notifier.clone();
move |_, _| notifier.borrow_mut().signal_received()
move |_, _, _| notifier.borrow_mut().signal_received()
})
.map_err(move |e| {
// the backend in the closure should already have been dropped
@ -437,7 +442,12 @@ pub fn direct_session_bind<Data: 'static>(
.into_inner();
(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

View File

@ -19,11 +19,7 @@ use std::{
};
use udev::{Enumerator, EventType, MonitorBuilder, MonitorSocket};
use calloop::{
generic::{Generic, SourceFd},
mio::Interest,
InsertError, LoopHandle, Source,
};
use calloop::{generic::Generic, InsertError, LoopHandle, Source};
/// 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
pub type UdevSource<T> = Generic<SourceFd<UdevBackend<T>>>;
pub type UdevSource<T> = Generic<UdevBackend<T>>;
/// 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>,
handle: &LoopHandle<Data>,
) -> Result<Source<UdevSource<T>>, InsertError<UdevSource<T>>> {
let mut source = Generic::from_fd_source(udev);
source.set_interest(Interest::READABLE);
let source = Generic::new(udev, calloop::Interest::Readable, calloop::Mode::Level);
handle.insert_source(source, |evt, _| {
evt.source.borrow_mut().0.process_events();
handle.insert_source(source, |_, backend, _| {
backend.process_events();
Ok(())
})
}

View File

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