@@ -107,15 +107,18 @@ async fn transfer_monitor(
107
107
) -> Result < ( ) > {
108
108
let mut usb_bytes_out_last: usize = 0 ;
109
109
let mut tcp_bytes_out_last: usize = 0 ;
110
+ let mut stall_usb_bytes_last: usize = 0 ;
111
+ let mut stall_tcp_bytes_last: usize = 0 ;
110
112
let mut report_time = Instant :: now ( ) ;
113
+ let mut stall_check = Instant :: now ( ) ;
111
114
112
115
loop {
116
+ // load current total transfer from AtomicUsize:
117
+ let usb_bytes_out = usb_bytes_written. load ( Ordering :: Relaxed ) ;
118
+ let tcp_bytes_out = tcp_bytes_written. load ( Ordering :: Relaxed ) ;
119
+
113
120
// Stats printing
114
121
if stats_interval. is_some ( ) && report_time. elapsed ( ) > stats_interval. unwrap ( ) {
115
- // load current total transfer from AtomicUsize:
116
- let usb_bytes_out = usb_bytes_written. load ( Ordering :: Relaxed ) ;
117
- let tcp_bytes_out = tcp_bytes_written. load ( Ordering :: Relaxed ) ;
118
-
119
122
// compute USB transfer
120
123
usb_bytes_out_last = usb_bytes_out - usb_bytes_out_last;
121
124
let usb_transferred_total = ByteSize :: b ( usb_bytes_out. try_into ( ) . unwrap ( ) ) ;
@@ -151,6 +154,22 @@ async fn transfer_monitor(
151
154
tcp_bytes_out_last = tcp_bytes_out;
152
155
}
153
156
157
+ // transfer stall detection
158
+ if stall_check. elapsed ( ) > READ_TIMEOUT {
159
+ // compute delta since last check
160
+ stall_usb_bytes_last = usb_bytes_out - stall_usb_bytes_last;
161
+ stall_tcp_bytes_last = tcp_bytes_out - stall_tcp_bytes_last;
162
+
163
+ if stall_usb_bytes_last == 0 || stall_tcp_bytes_last == 0 {
164
+ return Err ( "unexpected transfer stall" . into ( ) ) ;
165
+ }
166
+
167
+ // save values for next iteration
168
+ stall_check = Instant :: now ( ) ;
169
+ stall_usb_bytes_last = usb_bytes_out;
170
+ stall_tcp_bytes_last = tcp_bytes_out;
171
+ }
172
+
154
173
sleep ( Duration :: from_millis ( 100 ) ) . await ;
155
174
}
156
175
}
0 commit comments