Merge pull request #367 from PolyMeilex/fix-2
backend.libseat: Fix dispatch double borrow
This commit is contained in:
commit
d0ee7d831e
|
@ -25,6 +25,7 @@
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
|
||||||
- EGLBufferReader now checks if buffers are alive before using them.
|
- EGLBufferReader now checks if buffers are alive before using them.
|
||||||
|
- LibSeat no longer panics on seat disable event.
|
||||||
|
|
||||||
## version 0.3.0 (2021-07-25)
|
## version 0.3.0 (2021-07-25)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,10 @@ use std::{
|
||||||
|
|
||||||
use nix::{errno::Errno, fcntl::OFlag, unistd::close};
|
use nix::{errno::Errno, fcntl::OFlag, unistd::close};
|
||||||
|
|
||||||
use calloop::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
|
use calloop::{
|
||||||
|
channel::{self, Channel},
|
||||||
|
EventSource, Poll, PostAction, Readiness, Token, TokenFactory,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::session::{AsErrno, Session, Signal as SessionSignal},
|
backend::session::{AsErrno, Session, Signal as SessionSignal},
|
||||||
|
@ -53,6 +56,7 @@ pub struct LibSeatSession {
|
||||||
pub struct LibSeatSessionNotifier {
|
pub struct LibSeatSessionNotifier {
|
||||||
internal: Rc<LibSeatSessionImpl>,
|
internal: Rc<LibSeatSessionImpl>,
|
||||||
signaler: Signaler<SessionSignal>,
|
signaler: Signaler<SessionSignal>,
|
||||||
|
rx: Channel<SeatEvent>,
|
||||||
token: Token,
|
token: Token,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,26 +69,20 @@ impl LibSeatSession {
|
||||||
let logger = crate::slog_or_fallback(logger)
|
let logger = crate::slog_or_fallback(logger)
|
||||||
.new(o!("smithay_module" => "backend_session", "session_type" => "libseat"));
|
.new(o!("smithay_module" => "backend_session", "session_type" => "libseat"));
|
||||||
|
|
||||||
let active = Arc::new(AtomicBool::new(false));
|
let (tx, rx) = calloop::channel::channel();
|
||||||
let signaler = Signaler::new();
|
|
||||||
|
|
||||||
let seat = {
|
let seat = {
|
||||||
let log = logger.clone();
|
let log = logger.clone();
|
||||||
let active = active.clone();
|
|
||||||
let signaler = signaler.clone();
|
|
||||||
|
|
||||||
Seat::open(
|
Seat::open(
|
||||||
move |seat, event| match event {
|
move |_seat, event| match event {
|
||||||
SeatEvent::Enable => {
|
SeatEvent::Enable => {
|
||||||
debug!(log, "Enable callback called");
|
debug!(log, "Enable callback called");
|
||||||
active.store(true, Ordering::SeqCst);
|
tx.send(event).unwrap();
|
||||||
signaler.signal(SessionSignal::ActivateSession);
|
|
||||||
}
|
}
|
||||||
SeatEvent::Disable => {
|
SeatEvent::Disable => {
|
||||||
debug!(log, "Disable callback called");
|
debug!(log, "Disable callback called");
|
||||||
active.store(false, Ordering::SeqCst);
|
tx.send(event).unwrap();
|
||||||
signaler.signal(SessionSignal::PauseSession);
|
|
||||||
seat.disable().unwrap();
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logger.clone(),
|
logger.clone(),
|
||||||
|
@ -92,30 +90,32 @@ impl LibSeatSession {
|
||||||
};
|
};
|
||||||
|
|
||||||
seat.map(|mut seat| {
|
seat.map(|mut seat| {
|
||||||
|
let seat_name = seat.name().to_owned();
|
||||||
|
|
||||||
// In some cases enable_seat event is avalible right after startup
|
// In some cases enable_seat event is avalible right after startup
|
||||||
// so, we can dispatch it
|
// so, we can dispatch it
|
||||||
seat.dispatch(0).unwrap();
|
seat.dispatch(0).unwrap();
|
||||||
|
|
||||||
let seat_name = seat.name().to_owned();
|
|
||||||
|
|
||||||
let internal = Rc::new(LibSeatSessionImpl {
|
let internal = Rc::new(LibSeatSessionImpl {
|
||||||
seat: RefCell::new(seat),
|
seat: RefCell::new(seat),
|
||||||
active,
|
active: Arc::new(AtomicBool::new(false)),
|
||||||
devices: RefCell::new(HashMap::new()),
|
devices: RefCell::new(HashMap::new()),
|
||||||
logger,
|
logger,
|
||||||
});
|
});
|
||||||
|
|
||||||
(
|
let session = LibSeatSession {
|
||||||
LibSeatSession {
|
internal: Rc::downgrade(&internal),
|
||||||
internal: Rc::downgrade(&internal),
|
seat_name,
|
||||||
seat_name,
|
};
|
||||||
},
|
|
||||||
LibSeatSessionNotifier {
|
let notifier = LibSeatSessionNotifier {
|
||||||
internal,
|
internal,
|
||||||
signaler,
|
signaler: Signaler::new(),
|
||||||
token: Token::invalid(),
|
rx,
|
||||||
},
|
token: Token::invalid(),
|
||||||
)
|
};
|
||||||
|
|
||||||
|
(session, notifier)
|
||||||
})
|
})
|
||||||
.map_err(|err| Error::FailedToOpenSession(Errno::from_i32(err.into())))
|
.map_err(|err| Error::FailedToOpenSession(Errno::from_i32(err.into())))
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ impl Session for LibSeatSession {
|
||||||
if let Some(session) = self.internal.upgrade() {
|
if let Some(session) = self.internal.upgrade() {
|
||||||
debug!(session.logger, "Closing device: {:?}", fd);
|
debug!(session.logger, "Closing device: {:?}", fd);
|
||||||
|
|
||||||
let dev = session.devices.borrow().get(&fd).map(|fd| *fd);
|
let dev = session.devices.borrow().get(&fd).copied();
|
||||||
|
|
||||||
let out = if let Some(dev) = dev {
|
let out = if let Some(dev) = dev {
|
||||||
session
|
session
|
||||||
|
@ -214,17 +214,38 @@ impl EventSource for LibSeatSessionNotifier {
|
||||||
type Metadata = ();
|
type Metadata = ();
|
||||||
type Ret = ();
|
type Ret = ();
|
||||||
|
|
||||||
fn process_events<F>(&mut self, _readiness: Readiness, token: Token, _: F) -> std::io::Result<PostAction>
|
fn process_events<F>(&mut self, readiness: Readiness, token: Token, _: F) -> std::io::Result<PostAction>
|
||||||
where
|
where
|
||||||
F: FnMut((), &mut ()),
|
F: FnMut((), &mut ()),
|
||||||
{
|
{
|
||||||
if token == self.token {
|
if token == self.token {
|
||||||
self.internal.seat.borrow_mut().dispatch(0).unwrap();
|
self.internal.seat.borrow_mut().dispatch(0).unwrap();
|
||||||
}
|
}
|
||||||
Ok(PostAction::Continue)
|
|
||||||
|
let internal = &self.internal;
|
||||||
|
let signaler = &self.signaler;
|
||||||
|
|
||||||
|
self.rx.process_events(readiness, token, |event, _| match event {
|
||||||
|
channel::Event::Msg(event) => match event {
|
||||||
|
SeatEvent::Enable => {
|
||||||
|
internal.active.store(true, Ordering::SeqCst);
|
||||||
|
signaler.signal(SessionSignal::ActivateSession);
|
||||||
|
}
|
||||||
|
SeatEvent::Disable => {
|
||||||
|
internal.active.store(false, Ordering::SeqCst);
|
||||||
|
signaler.signal(SessionSignal::PauseSession);
|
||||||
|
internal.seat.borrow_mut().disable().unwrap();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
channel::Event::Closed => {
|
||||||
|
// Tx is stored inside of Seat, and Rc<Seat> is stored in LibSeatSessionNotifier so this is unreachable
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> std::io::Result<()> {
|
fn register(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> std::io::Result<()> {
|
||||||
|
self.rx.register(poll, factory)?;
|
||||||
|
|
||||||
self.token = factory.token();
|
self.token = factory.token();
|
||||||
poll.register(
|
poll.register(
|
||||||
self.internal.seat.borrow_mut().get_fd().unwrap(),
|
self.internal.seat.borrow_mut().get_fd().unwrap(),
|
||||||
|
@ -232,11 +253,11 @@ impl EventSource for LibSeatSessionNotifier {
|
||||||
calloop::Mode::Level,
|
calloop::Mode::Level,
|
||||||
self.token,
|
self.token,
|
||||||
)
|
)
|
||||||
.unwrap();
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reregister(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> std::io::Result<()> {
|
fn reregister(&mut self, poll: &mut Poll, factory: &mut TokenFactory) -> std::io::Result<()> {
|
||||||
|
self.rx.reregister(poll, factory)?;
|
||||||
|
|
||||||
self.token = factory.token();
|
self.token = factory.token();
|
||||||
poll.reregister(
|
poll.reregister(
|
||||||
self.internal.seat.borrow_mut().get_fd().unwrap(),
|
self.internal.seat.borrow_mut().get_fd().unwrap(),
|
||||||
|
@ -244,15 +265,13 @@ impl EventSource for LibSeatSessionNotifier {
|
||||||
calloop::Mode::Level,
|
calloop::Mode::Level,
|
||||||
self.token,
|
self.token,
|
||||||
)
|
)
|
||||||
.unwrap();
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
fn unregister(&mut self, poll: &mut Poll) -> std::io::Result<()> {
|
||||||
|
self.rx.unregister(poll)?;
|
||||||
|
|
||||||
self.token = Token::invalid();
|
self.token = Token::invalid();
|
||||||
poll.unregister(self.internal.seat.borrow_mut().get_fd().unwrap())
|
poll.unregister(self.internal.seat.borrow_mut().get_fd().unwrap())
|
||||||
.unwrap();
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue