Add comment explaining thread::spawn timeout.

This commit is contained in:
sklv
2020-04-12 11:06:29 +00:00
committed by Martin Algesten
parent b0898ae8fd
commit a598b1091b

View File

@@ -282,6 +282,17 @@ fn connect_socks5(
)); ));
} }
// Since Socks5Stream doesn't support set_read_timeout, a suboptimal one is implemented via
// thread::spawn.
// # Happy Path
// 1) thread spawns 2) get_socks5_stream returns ok 3) tx sends result ok
// 4) slave_signal signals done and cvar notifies master_signal 5) cvar.wait_timeout receives the done signal
// 6) rx receives the socks5 stream and the function exists
// # Sad path
// 1) get_socks5_stream hangs 2)slave_signal does not send done notification 3) cvar.wait_timeout times out
// 3) an exception is thrown.
// # Defects
// 1) In the event of a timeout, a thread may be left running in the background.
let stream = if timeout_connect > 0 { let stream = if timeout_connect > 0 {
let master_signal = Arc::new((Mutex::new(false), Condvar::new())); let master_signal = Arc::new((Mutex::new(false), Condvar::new()));
let slave_signal = master_signal.clone(); let slave_signal = master_signal.clone();
@@ -289,12 +300,15 @@ fn connect_socks5(
let host_addr = host_addrs[0]; let host_addr = host_addrs[0];
thread::spawn(move || { thread::spawn(move || {
let (lock, cvar) = &*slave_signal; let (lock, cvar) = &*slave_signal;
if tx if tx // try to get a socks5 stream and send it to the parent thread's rx
.send(get_socks5_stream(&proxy, &proxy_addr, &host_addr)) .send(get_socks5_stream(&proxy, &proxy_addr, &host_addr))
.is_ok() .is_ok()
{ {
// if sending the stream has succeeded we need to notify the parent thread
let mut done = lock.lock().unwrap(); let mut done = lock.lock().unwrap();
// set the done signal to true
*done = true; *done = true;
// notify the parent thread
cvar.notify_one(); cvar.notify_one();
} }
}); });