Automatically close client's windows on disconnect
This commit is contained in:
parent
e624edc36f
commit
28c6a3e1e6
|
@ -1,12 +1,11 @@
|
|||
use std::io::Read;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::from_utf8;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use magpie_types::{CreatePanel, MagpieClientMsg, MagpieServerMsg, ServerMessenger};
|
||||
use magpie_types::{CreatePanel, MagpieServerMsg, ServerMessenger};
|
||||
use mio::net::{UnixListener, UnixStream};
|
||||
use mio::{Events, Interest, Poll, Token, Waker};
|
||||
use mio_signals::{Signal, Signals};
|
||||
|
@ -55,6 +54,15 @@ impl DerefMut for Listener {
|
|||
|
||||
pub struct IpcData {
|
||||
poll: Poll,
|
||||
next_window_id: usize,
|
||||
}
|
||||
|
||||
impl IpcData {
|
||||
pub fn new_window_id(&mut self) -> usize {
|
||||
let id = self.next_window_id;
|
||||
self.next_window_id = self.next_window_id.wrapping_add(1);
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Client {
|
||||
|
@ -62,6 +70,23 @@ pub struct Client {
|
|||
window_sender: WindowMessageSender,
|
||||
messenger: ServerMessenger<UnixStream>,
|
||||
token: Token,
|
||||
id_to_window: HashMap<u32, usize>,
|
||||
}
|
||||
|
||||
impl Drop for Client {
|
||||
fn drop(&mut self) {
|
||||
println!("Client #{} disconnected", self.token.0);
|
||||
let data = self.data.write();
|
||||
let _ = data
|
||||
.poll
|
||||
.registry()
|
||||
.deregister(&mut self.messenger.transport);
|
||||
|
||||
for (_id, window) in self.id_to_window.drain() {
|
||||
let msg = WindowMessage::CloseWindow { id: window };
|
||||
let _ = self.window_sender.send_event(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
|
@ -72,8 +97,14 @@ impl Client {
|
|||
println!("Client #{}: {:?}", self.token.0, msg);
|
||||
match msg {
|
||||
MagpieServerMsg::CreatePanel(CreatePanel { id }) => {
|
||||
let id = id as usize;
|
||||
let msg = WindowMessage::OpenWindow { id };
|
||||
let window = self.data.write().new_window_id();
|
||||
|
||||
if let Some(old_id) = self.id_to_window.insert(id, window) {
|
||||
let msg = WindowMessage::CloseWindow { id: old_id };
|
||||
let _ = self.window_sender.send_event(msg);
|
||||
}
|
||||
|
||||
let msg = WindowMessage::OpenWindow { id: window };
|
||||
let _ = self.window_sender.send_event(msg);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
|
@ -130,7 +161,10 @@ impl Ipc {
|
|||
sender,
|
||||
};
|
||||
|
||||
let data = IpcData { poll };
|
||||
let data = IpcData {
|
||||
poll,
|
||||
next_window_id: 0,
|
||||
};
|
||||
|
||||
let ipc = Self {
|
||||
data: Arc::new(RwLock::new(data)),
|
||||
|
@ -175,6 +209,7 @@ impl Ipc {
|
|||
token,
|
||||
data: self.data.clone(),
|
||||
window_sender: self.window_sender.clone(),
|
||||
id_to_window: Default::default(),
|
||||
});
|
||||
}
|
||||
Err(ref err) if err.kind() == std::io::ErrorKind::WouldBlock => break,
|
||||
|
@ -190,13 +225,7 @@ impl Ipc {
|
|||
} else if let Some(client) = self.clients.get_mut(event.token().0) {
|
||||
let disconnected = client.on_readable()?;
|
||||
if disconnected {
|
||||
println!("Client #{} disconnected", event.token().0);
|
||||
let mut client = self.clients.remove(event.token().0);
|
||||
self.data
|
||||
.write()
|
||||
.poll
|
||||
.registry()
|
||||
.deregister(&mut client.messenger.transport)?;
|
||||
self.clients.remove(event.token().0);
|
||||
}
|
||||
} else {
|
||||
panic!("Unrecognized event token: {:?}", event);
|
||||
|
|
Loading…
Reference in New Issue