diff --git a/examples/ping.rs b/examples/ping.rs index bdf8baa..07d9b9f 100644 --- a/examples/ping.rs +++ b/examples/ping.rs @@ -19,7 +19,7 @@ fn main() -> Result<(), Box> { pinger.add_ipaddr("1.1.1.1".parse()?); pinger.add_ipaddr("7.7.7.7".parse()?); pinger.add_ipaddr("2001:4860:4860::8888".parse()?); - pinger.run(); + pinger.run()?; loop { match results.recv() { diff --git a/src/lib.rs b/src/lib.rs index daab1d1..de4fd16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ extern crate log; pub mod error; pub mod transport; -use crate::error::*; +use crate::error::Error; use crate::transport::{Ping, PingTransport, ReceivedPing}; use std::collections::BTreeMap; use std::net::IpAddr; @@ -148,11 +148,14 @@ impl Pinger { /// /// This consumes the [`Pinger`] object and returns a new [`RunningPinger`]. The original /// [`Pinger`] may be obtained from [`RunningPinger::stop`]. - pub fn run(mut self) -> RunningPinger { + /// + /// An [`Err`] variant is returned if a thread can not be created for the [`Pinger`]. + pub fn run(mut self) -> Result, Error> { let stop = Arc::new(AtomicBool::new(false)); let stop_inner = stop.clone(); let targets = self.targets.clone(); - let join_handle = thread::spawn(move || loop { + let builder = thread::Builder::new().name("pinger".into()); + let join_handle = builder.spawn(move || loop { let start = Instant::now(); // Work self.ping_once(); @@ -164,13 +167,13 @@ impl Pinger { // If we received all replies faster than the interval, wait thread::sleep(self.max_rtt.saturating_sub(start.elapsed())); - }); + })?; - RunningPinger { + Ok(RunningPinger { stop, join_handle, targets, - } + }) } fn await_replies(&self, timer: Instant, sent: usize) { @@ -377,7 +380,7 @@ mod tests { let targets_len = pinger.targets.lock().unwrap().len(); // Copy attributes of the original Pinger let max_rtt = pinger.max_rtt; - let stop_handle = pinger.run(); + let stop_handle = pinger.run()?; let pinger = stop_handle.stop().unwrap(); // Try to verify we have the same Pinger back. Other attributes can't be cloned. assert_eq!(max_rtt, pinger.max_rtt); diff --git a/src/transport/pnet.rs b/src/transport/pnet.rs index f2cef82..73b65fa 100644 --- a/src/transport/pnet.rs +++ b/src/transport/pnet.rs @@ -70,7 +70,7 @@ impl crate::transport::PingTransport for PingTransport { timer: Arc::new(RwLock::new(Instant::now())), }; - start_listener(rx, rxv6, resp_sender, transport.timer.clone()); + start_listener(rx, rxv6, resp_sender, transport.timer.clone())?; Ok(transport) } @@ -163,18 +163,21 @@ fn start_listener( rxv6: TransportReceiver, resp_sender: Sender, timer: Arc>, -) { +) -> Result<(), Error> { // start icmp listeners in the background and use internal channels for results - start_listener_v4(rxv4, resp_sender.clone(), timer.clone()); - start_listener_v6(rxv6, resp_sender.clone(), timer.clone()); + start_listener_v4(rxv4, resp_sender.clone(), timer.clone())?; + start_listener_v6(rxv6, resp_sender.clone(), timer.clone())?; + + Ok(()) } fn start_listener_v4( mut receiver: TransportReceiver, resp_sender: Sender, timer: Arc>, -) { - thread::spawn(move || { +) -> Result<(), Error> { + let builder = thread::Builder::new().name("pnet-v4-listener".into()); + builder.spawn(move || { let mut iter = icmp_packet_iter(&mut receiver); loop { match iter.next() { @@ -206,15 +209,18 @@ fn start_listener_v4( } } } - }); + })?; + + Ok(()) } fn start_listener_v6( mut receiver: TransportReceiver, resp_sender: Sender, timer: Arc>, -) { - thread::spawn(move || { +) -> Result<(), Error> { + let builder = thread::Builder::new().name("pnet-v6-listener".into()); + builder.spawn(move || { let mut iter = icmpv6_packet_iter(&mut receiver); loop { match iter.next() { @@ -246,5 +252,7 @@ fn start_listener_v6( } } } - }); + })?; + + Ok(()) }