diff --git a/TODO.md b/TODO.md index 799e7ad..77dfc16 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,6 @@ ## aquatic_ws * is it even necessary to check if event is readable in poll, since that is all we're listening for? -* error in workers: print it, exit program with non-zero exit code * privdrop * add sensible logging method, maybe stderrlog with quiet as default diff --git a/aquatic_ws/src/lib/common.rs b/aquatic_ws/src/lib/common.rs index 2e3ad00..355d367 100644 --- a/aquatic_ws/src/lib/common.rs +++ b/aquatic_ws/src/lib/common.rs @@ -126,4 +126,8 @@ impl OutMessageSender { ){ self.0[meta.worker_index].send((meta, message)); } -} \ No newline at end of file +} + + +pub type SocketWorkerStatus = Option>; +pub type SocketWorkerStatuses = Arc>>; \ No newline at end of file diff --git a/aquatic_ws/src/lib/lib.rs b/aquatic_ws/src/lib/lib.rs index 510cb4a..be1527c 100644 --- a/aquatic_ws/src/lib/lib.rs +++ b/aquatic_ws/src/lib/lib.rs @@ -1,7 +1,9 @@ use std::time::Duration; use std::fs::File; use std::io::Read; +use std::sync::Arc; use native_tls::{Identity, TlsAcceptor}; +use parking_lot::Mutex; pub mod common; pub mod config; @@ -23,8 +25,19 @@ pub fn run(config: Config) -> anyhow::Result<()> { let mut out_message_senders = Vec::new(); + let socket_worker_statuses: SocketWorkerStatuses = { + let mut statuses = Vec::new(); + + for _ in 0..config.socket_workers { + statuses.push(None); + } + + Arc::new(Mutex::new(statuses)) + }; + for i in 0..config.socket_workers { let config = config.clone(); + let socket_worker_statuses = socket_worker_statuses.clone(); let in_message_sender = in_message_sender.clone(); let opt_tls_acceptor = opt_tls_acceptor.clone(); @@ -36,6 +49,7 @@ pub fn run(config: Config) -> anyhow::Result<()> { network::run_socket_worker( config, i, + socket_worker_statuses, in_message_sender, out_message_receiver, opt_tls_acceptor @@ -43,6 +57,27 @@ pub fn run(config: Config) -> anyhow::Result<()> { }); } + // Wait for socket worker statuses. On error from any, quit program. + // On success from all, continue program. + loop { + ::std::thread::sleep(::std::time::Duration::from_millis(10)); + + if let Some(statuses) = socket_worker_statuses.try_lock(){ + for opt_status in statuses.iter(){ + match opt_status { + Some(Err(err)) => { + return Err(::anyhow::anyhow!(err.to_owned())); + }, + _ => {}, + } + } + + if statuses.iter().all(Option::is_some){ + break + } + } + } + let out_message_sender = OutMessageSender::new(out_message_senders); { diff --git a/aquatic_ws/src/lib/network/mod.rs b/aquatic_ws/src/lib/network/mod.rs index 8276801..62a49e4 100644 --- a/aquatic_ws/src/lib/network/mod.rs +++ b/aquatic_ws/src/lib/network/mod.rs @@ -22,12 +22,15 @@ use utils::*; pub fn run_socket_worker( config: Config, socket_worker_index: usize, + socket_worker_statuses: SocketWorkerStatuses, in_message_sender: InMessageSender, out_message_receiver: OutMessageReceiver, opt_tls_acceptor: Option, ){ match create_listener(&config){ Ok(listener) => { + socket_worker_statuses.lock()[socket_worker_index] = Some(Ok(())); + run_poll_loop( config, socket_worker_index, @@ -38,7 +41,9 @@ pub fn run_socket_worker( ); }, Err(err) => { - eprintln!("Couldn't create TCP listener: {}", err) + socket_worker_statuses.lock()[socket_worker_index] = Some( + Err(format!("Couldn't create TCP listener: {}", err)) + ); } } }