From 411f34e6ce3c37615ca6b33a9bd570516937d07a Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Sat, 16 May 2020 19:26:52 +0100 Subject: [PATCH] Make disconnection clean up completely Now we can disconnect and reconnect the same account multiple times. --- README.md | 2 +- src/padfoot/connection.rs | 22 ++++++++++++++++------ src/padfoot/connection_manager.rs | 8 ++++---- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a24b187..b79c507 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Here's where we're at right now: - [x] Connect to deltachat-core-rust - [x] Set up an account via autoconfiguration - [x] Appear as online in Empathy -- [~] Disconnect! +- [x] Disconnect! - [ ] Set up an account manually - [ ] Contacts handling - [ ] Text messages diff --git a/src/padfoot/connection.rs b/src/padfoot/connection.rs index 7cfffa0..06f605c 100644 --- a/src/padfoot/connection.rs +++ b/src/padfoot/connection.rs @@ -28,7 +28,7 @@ use dc::context::Context; use dc::Event; use deltachat as dc; -use std::collections::{HashMap, VecDeque}; +use std::collections::{HashMap, HashSet, VecDeque}; use std::sync::{mpsc, Arc, Mutex, RwLock}; use std::time::Duration; @@ -38,6 +38,9 @@ pub const CONN_OBJECT_PATH: &str = "/org/freedesktop/Telepathy/Connection/padfoo #[derive(Debug)] // A Deltachast connection uses email addresses as handles, and delta's Db IDs pub struct Connection { + // Remove ourselves from this when done + conns: Arc>>, + ctx: Arc>, settings: ConnSettings, state: Arc>, @@ -96,7 +99,10 @@ impl ConnSettings { } impl Connection { - pub fn new(settings: ConnSettings) -> Result { + pub fn new( + settings: ConnSettings, + conns: Arc>>, + ) -> Result { let mut dbfile = directories::ProjectDirs::from("gs", "ur", "telepathy-padfoot") .ok_or_else(MethodErr::no_arg) .and_then(|p| Ok(p.data_local_dir().to_path_buf()))?; @@ -169,6 +175,7 @@ impl Connection { }; Ok(Connection { + conns, settings, msgq, ctx: Arc::new(RwLock::new(ctx)), @@ -184,6 +191,7 @@ impl Connection { pub fn run(self, signal: mpsc::Sender>) { let bus = self.bus(); let path = self.path(); + let conns = self.conns.clone(); let state = self.state.clone(); let msgq = self.msgq.clone(); let id = self.id(); @@ -215,7 +223,7 @@ impl Connection { telepathy::connection_interface_simple_presence_server(&f, (), move |_| c_rc.clone()); tree = tree.add( - f.object_path(path, ()) + f.object_path(path.clone(), ()) .introspectable() .add(conn_iface) .add(avatars_iface) @@ -262,7 +270,7 @@ impl Connection { if let Err(e) = c.process(Duration::from_millis(100)) { println!("Error processing: {}", e); - return; + break; }; // Spend a bit of time sending any outgoing messages - signals, mostly @@ -276,8 +284,10 @@ impl Connection { } } - // TODO: clean up, emit disconnected signal. Join on threads started in - // connect() ? + // TODO: join on threads started in connect! + + let mut conns = conns.lock().expect("Mutex access"); + conns.remove(&path); } pub fn id(&self) -> String { diff --git a/src/padfoot/connection_manager.rs b/src/padfoot/connection_manager.rs index 84c6d2c..f055100 100644 --- a/src/padfoot/connection_manager.rs +++ b/src/padfoot/connection_manager.rs @@ -4,7 +4,7 @@ use dbus::arg; use dbus::message::SignalArgs; use dbus::tree::MethodErr; use std::collections::{HashMap, HashSet}; -use std::sync::mpsc; +use std::sync::{mpsc, Arc, Mutex}; use super::{ConnSettings, Connection}; @@ -14,7 +14,7 @@ pub const CM_OBJECT_PATH: &str = "/org/freedesktop/Telepathy/ConnectionManager/p #[derive(Debug)] pub struct ConnectionManager { - conns: std::sync::Mutex>, + conns: Arc>>, sender: mpsc::Sender, } @@ -30,7 +30,7 @@ impl ConnectionManager { ( ConnectionManager { - conns: std::sync::Mutex::new(HashSet::::new()), + conns: Arc::new(Mutex::new(HashSet::::new())), sender: msg_s, }, msg_r, @@ -54,7 +54,7 @@ impl ConnectionManager { return Err(MethodErr::no_arg()); } - let conn = Connection::new(settings)?; + let conn = Connection::new(settings, self.conns.clone())?; // It would be nice to have a single main loop, but thread-per-conn is // is easy enough for me to understand in Rust at the moment.