mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-04-16 09:51:28 +03:00
Fix Error handling in layershell producer (#61)
previous error handling resulted in a softlock when the connection to the compositor was lost
This commit is contained in:
committed by
GitHub
parent
f5827bb31c
commit
6cdb607b11
@@ -24,9 +24,13 @@ impl Default for DummyProducer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EventProducer for DummyProducer {
|
impl EventProducer for DummyProducer {
|
||||||
fn notify(&mut self, _: ClientEvent) {}
|
fn notify(&mut self, _event: ClientEvent) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn release(&mut self) {}
|
fn release(&mut self) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for DummyProducer {
|
impl Stream for DummyProducer {
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ use std::{io, task::Poll};
|
|||||||
|
|
||||||
use futures_core::Stream;
|
use futures_core::Stream;
|
||||||
|
|
||||||
use crate::{client::ClientHandle, event::Event, producer::EventProducer};
|
use crate::{
|
||||||
|
client::{ClientEvent, ClientHandle},
|
||||||
|
event::Event,
|
||||||
|
producer::EventProducer,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct LibeiProducer {}
|
pub struct LibeiProducer {}
|
||||||
|
|
||||||
@@ -14,9 +18,13 @@ impl LibeiProducer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EventProducer for LibeiProducer {
|
impl EventProducer for LibeiProducer {
|
||||||
fn notify(&mut self, _event: crate::client::ClientEvent) {}
|
fn notify(&mut self, _event: ClientEvent) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn release(&mut self) {}
|
fn release(&mut self) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for LibeiProducer {
|
impl Stream for LibeiProducer {
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ impl Stream for MacOSProducer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EventProducer for MacOSProducer {
|
impl EventProducer for MacOSProducer {
|
||||||
fn notify(&mut self, _event: ClientEvent) {}
|
fn notify(&mut self, _event: ClientEvent) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn release(&mut self) {}
|
fn release(&mut self) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -527,24 +527,25 @@ impl Inner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush_events(&mut self) {
|
fn flush_events(&mut self) -> io::Result<()> {
|
||||||
// flush outgoing events
|
// flush outgoing events
|
||||||
match self.queue.flush() {
|
match self.queue.flush() {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
WaylandError::Io(e) => {
|
WaylandError::Io(e) => {
|
||||||
log::error!("error writing to wayland socket: {e}")
|
return Err(e);
|
||||||
}
|
}
|
||||||
WaylandError::Protocol(e) => {
|
WaylandError::Protocol(e) => {
|
||||||
panic!("wayland protocol violation: {e}")
|
panic!("wayland protocol violation: {e}")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventProducer for WaylandEventProducer {
|
impl EventProducer for WaylandEventProducer {
|
||||||
fn notify(&mut self, client_event: ClientEvent) {
|
fn notify(&mut self, client_event: ClientEvent) -> io::Result<()> {
|
||||||
match client_event {
|
match client_event {
|
||||||
ClientEvent::Create(handle, pos) => {
|
ClientEvent::Create(handle, pos) => {
|
||||||
self.0.get_mut().state.add_client(handle, pos);
|
self.0.get_mut().state.add_client(handle, pos);
|
||||||
@@ -564,14 +565,14 @@ impl EventProducer for WaylandEventProducer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let inner = self.0.get_mut();
|
let inner = self.0.get_mut();
|
||||||
inner.flush_events();
|
inner.flush_events()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release(&mut self) {
|
fn release(&mut self) -> io::Result<()> {
|
||||||
log::debug!("releasing pointer");
|
log::debug!("releasing pointer");
|
||||||
let inner = self.0.get_mut();
|
let inner = self.0.get_mut();
|
||||||
inner.state.ungrab();
|
inner.state.ungrab();
|
||||||
inner.flush_events();
|
inner.flush_events()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,7 +603,11 @@ impl Stream for WaylandEventProducer {
|
|||||||
inner.dispatch_events();
|
inner.dispatch_events();
|
||||||
|
|
||||||
// flush outgoing events
|
// flush outgoing events
|
||||||
inner.flush_events();
|
if let Err(e) = inner.flush_events() {
|
||||||
|
if e.kind() != ErrorKind::WouldBlock {
|
||||||
|
return Poll::Ready(Some(Err(e)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// prepare for the next read
|
// prepare for the next read
|
||||||
match inner.prepare_read() {
|
match inner.prepare_read() {
|
||||||
|
|||||||
@@ -12,9 +12,13 @@ use crate::{
|
|||||||
pub struct WindowsProducer {}
|
pub struct WindowsProducer {}
|
||||||
|
|
||||||
impl EventProducer for WindowsProducer {
|
impl EventProducer for WindowsProducer {
|
||||||
fn notify(&mut self, _: ClientEvent) {}
|
fn notify(&mut self, _event: ClientEvent) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn release(&mut self) {}
|
fn release(&mut self) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowsProducer {
|
impl WindowsProducer {
|
||||||
|
|||||||
@@ -18,9 +18,13 @@ impl X11Producer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EventProducer for X11Producer {
|
impl EventProducer for X11Producer {
|
||||||
fn notify(&mut self, _: ClientEvent) {}
|
fn notify(&mut self, _event: ClientEvent) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn release(&mut self) {}
|
fn release(&mut self) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for X11Producer {
|
impl Stream for X11Producer {
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ pub async fn create() -> Box<dyn EventProducer> {
|
|||||||
|
|
||||||
pub trait EventProducer: Stream<Item = io::Result<(ClientHandle, Event)>> + Unpin {
|
pub trait EventProducer: Stream<Item = io::Result<(ClientHandle, Event)>> + Unpin {
|
||||||
/// notify event producer of configuration changes
|
/// notify event producer of configuration changes
|
||||||
fn notify(&mut self, event: ClientEvent);
|
fn notify(&mut self, event: ClientEvent) -> io::Result<()>;
|
||||||
|
|
||||||
/// release mouse
|
/// release mouse
|
||||||
fn release(&mut self);
|
fn release(&mut self) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,18 +132,18 @@ impl Server {
|
|||||||
event = producer.next() => {
|
event = producer.next() => {
|
||||||
let event = event.ok_or(anyhow!("event producer closed"))??;
|
let event = event.ok_or(anyhow!("event producer closed"))??;
|
||||||
log::debug!("producer event: {event:?}");
|
log::debug!("producer event: {event:?}");
|
||||||
server.handle_producer_event(&mut producer, &sender_ch, &timer_ch, event).await;
|
server.handle_producer_event(&mut producer, &sender_ch, &timer_ch, event).await?;
|
||||||
}
|
}
|
||||||
e = producer_notify_rx.recv() => {
|
e = producer_notify_rx.recv() => {
|
||||||
log::debug!("producer notify rx: {e:?}");
|
log::debug!("producer notify rx: {e:?}");
|
||||||
match e {
|
match e {
|
||||||
Some(e) => match e {
|
Some(e) => match e {
|
||||||
ProducerEvent::Release => {
|
ProducerEvent::Release => {
|
||||||
producer.release();
|
producer.release()?;
|
||||||
server.state.replace(State::Receiving);
|
server.state.replace(State::Receiving);
|
||||||
|
|
||||||
}
|
}
|
||||||
ProducerEvent::ClientEvent(e) => producer.notify(e),
|
ProducerEvent::ClientEvent(e) => producer.notify(e)?,
|
||||||
ProducerEvent::Terminate => break,
|
ProducerEvent::Terminate => break,
|
||||||
},
|
},
|
||||||
None => break,
|
None => break,
|
||||||
@@ -426,35 +426,47 @@ impl Server {
|
|||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = signal::ctrl_c() => {
|
_ = signal::ctrl_c() => {
|
||||||
log::info!("terminating service");
|
log::info!("terminating service");
|
||||||
},
|
|
||||||
_ = &mut producer_task => {
|
|
||||||
// TODO restart producer?
|
|
||||||
}
|
}
|
||||||
_ = &mut consumer_task => {
|
e = &mut producer_task => {
|
||||||
// TODO restart producer?
|
if let Ok(Err(e)) = e {
|
||||||
|
log::error!("error in event producer: {e}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ = &mut frontend_task => {
|
e = &mut consumer_task => {
|
||||||
// frontend exited => exit requested
|
if let Ok(Err(e)) = e {
|
||||||
|
log::error!("error in event consumer: {e}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ = &mut resolver_task => {
|
e = &mut frontend_task => {
|
||||||
// resolver exited
|
if let Ok(Err(e)) = e {
|
||||||
}
|
log::error!("error in frontend listener: {e}");
|
||||||
_ = &mut udp_task => {
|
}
|
||||||
// udp exited
|
|
||||||
}
|
|
||||||
_ = &mut live_tracker => {
|
|
||||||
// live tracker exited
|
|
||||||
}
|
}
|
||||||
|
_ = &mut resolver_task => { }
|
||||||
|
_ = &mut udp_task => { }
|
||||||
|
_ = &mut live_tracker => { }
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = consumer_notify_tx.send(ConsumerEvent::Terminate).await;
|
let _ = consumer_notify_tx.send(ConsumerEvent::Terminate).await;
|
||||||
let _ = producer_notify_tx.send(ProducerEvent::Terminate).await;
|
let _ = producer_notify_tx.send(ProducerEvent::Terminate).await;
|
||||||
let _ = frontend_tx.send(FrontendEvent::Shutdown()).await;
|
let _ = frontend_tx.send(FrontendEvent::Shutdown()).await;
|
||||||
|
|
||||||
let (a, b, c) = tokio::join!(producer_task, consumer_task, frontend_task);
|
if !producer_task.is_finished() {
|
||||||
a??;
|
if let Err(e) = producer_task.await {
|
||||||
b??;
|
log::error!("error in event producer: {e}");
|
||||||
c??;
|
}
|
||||||
|
}
|
||||||
|
if !consumer_task.is_finished() {
|
||||||
|
if let Err(e) = consumer_task.await {
|
||||||
|
log::error!("error in event consumer: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !frontend_task.is_finished() {
|
||||||
|
if let Err(e) = frontend_task.await {
|
||||||
|
log::error!("error in frontend listener: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resolver_task.abort();
|
resolver_task.abort();
|
||||||
udp_task.abort();
|
udp_task.abort();
|
||||||
@@ -765,7 +777,7 @@ impl Server {
|
|||||||
sender_tx: &Sender<(Event, SocketAddr)>,
|
sender_tx: &Sender<(Event, SocketAddr)>,
|
||||||
timer_tx: &Sender<()>,
|
timer_tx: &Sender<()>,
|
||||||
event: (ClientHandle, Event),
|
event: (ClientHandle, Event),
|
||||||
) {
|
) -> Result<()> {
|
||||||
let (c, mut e) = event;
|
let (c, mut e) = event;
|
||||||
log::trace!("producer: ({c}) {e:?}");
|
log::trace!("producer: ({c}) {e:?}");
|
||||||
|
|
||||||
@@ -777,7 +789,7 @@ impl Server {
|
|||||||
}) = e
|
}) = e
|
||||||
{
|
{
|
||||||
if mods_depressed == Self::RELEASE_MODIFIERDS {
|
if mods_depressed == Self::RELEASE_MODIFIERDS {
|
||||||
producer.release();
|
producer.release()?;
|
||||||
self.state.replace(State::Receiving);
|
self.state.replace(State::Receiving);
|
||||||
log::trace!("STATE ===> Receiving");
|
log::trace!("STATE ===> Receiving");
|
||||||
// send an event to release all the modifiers
|
// send an event to release all the modifiers
|
||||||
@@ -796,10 +808,10 @@ impl Server {
|
|||||||
None => {
|
None => {
|
||||||
// should not happen
|
// should not happen
|
||||||
log::warn!("unknown client!");
|
log::warn!("unknown client!");
|
||||||
producer.release();
|
producer.release()?;
|
||||||
self.state.replace(State::Receiving);
|
self.state.replace(State::Receiving);
|
||||||
log::trace!("STATE ===> Receiving");
|
log::trace!("STATE ===> Receiving");
|
||||||
return;
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -825,6 +837,7 @@ impl Server {
|
|||||||
}
|
}
|
||||||
let _ = sender_tx.send((e, addr)).await;
|
let _ = sender_tx.send((e, addr)).await;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_frontend_stream(
|
async fn handle_frontend_stream(
|
||||||
|
|||||||
Reference in New Issue
Block a user