Pulling USB out is not detected and eats 100% CPU
Steps to reproduce
- Run basic_serial example and enter port name of plugged-in device
- Wait for console to calm down and pull the USB out
- Observe example loop is still running, console is clean, 1 CPU core is 100% utilized
Possible reason
This line is getting executed endlessly: https://github.com/meshtastic/rust/blob/923d2b7ec5b831a1fd2dc9f05d6d84424acfd3ec/src/connections/handlers.rs#L60 If I return an error here the example starts to work, but I'm not sure it will not break something else.
Confirming I can reproduce on my end in Linux.
One interesting thing I noticed, is that this happens even with the timeout set here:
https://github.com/meshtastic/rust/blob/e77d1683368a75d26f619a72d60070ecefef5470/src/utils_internal.rs#L115-L117
- This appears to be a bug in
tokio-serial(at least for FreeBSD): https://github.com/berkowski/tokio-serial/issues/56 - All the way at the bottom of the stack,
serialportdoes offer semantics for this,NoDeviceinbytes_to_read. ... but my best guess is they aren't percolating up to the stream's error, and just anOk(0)is returned.
I'm not sure it will not break something else.
@krant - Me either. start_read_handler is sufficiently generic enough to make it an unsafe bet.
I didn't have time to look much deeper into the chain of tokio-serial -> mio-serial -> serialport.
I have however, confirmed that changing the line to:
Ok(0) => { tokio::time::sleep(Duration::from_millis(5)).await; continue},
Will reduce the CPU usage down from 100%, which might be enough to make it tolerable in the meantime, until someone gets a chance to dig deeper.
tokio-serial example handles the pulling correctly:
cargo run --features="rt codec" --example serial_println -- /dev/ttyACM0
[LOG DATA]
## Pull out USB
[PROGRAM EXITS]
I seem to be able to reproduce this using the tcp_stream as well if the socket is closed.