@@ -25,6 +25,12 @@ use crate::{
2525 SerialPortBuilder , StopBits ,
2626} ;
2727
28+ const fn duration_to_win_timeout ( time : Duration ) -> DWORD {
29+ time. as_secs ( )
30+ . saturating_mul ( 1000 )
31+ . saturating_add ( ( time. subsec_nanos ( ) as u64 ) . saturating_div ( 1_000_000 ) ) as DWORD
32+ }
33+
2834struct OverlappedHandle ( pub HANDLE ) ;
2935
3036impl OverlappedHandle {
@@ -199,6 +205,33 @@ impl COMPort {
199205 port_name : None ,
200206 }
201207 }
208+
209+ ///Sets COM port timeouts.
210+ ///
211+ ///Comparing to `SerialPort::set_timeout` which only sets `read` timeout, this function allows
212+ ///to specify all available timeouts.
213+ ///
214+ ///- `data` - This timeout specifies how long to wait for next byte, since arrival of at least
215+ ///one byte. Once timeout expires, read returns with available data.
216+ ///`SerialPort::set_timeout` uses 0 which means no timeout.
217+ ///- `read` - Specifies overall timeout for `read` as `SerialPort::set_timeout`
218+ ///- `write` - Specifies overall timeout for `write` operations.
219+ pub fn set_timeouts ( & mut self , data : Duration , read : Duration , write : Duration ) -> Result < ( ) > {
220+ let mut timeouts = COMMTIMEOUTS {
221+ ReadIntervalTimeout : duration_to_win_timeout ( data) ,
222+ ReadTotalTimeoutMultiplier : 0 ,
223+ ReadTotalTimeoutConstant : duration_to_win_timeout ( read) ,
224+ WriteTotalTimeoutMultiplier : 0 ,
225+ WriteTotalTimeoutConstant : duration_to_win_timeout ( write) ,
226+ } ;
227+
228+ if unsafe { SetCommTimeouts ( self . handle , & mut timeouts) } == 0 {
229+ return Err ( super :: error:: last_os_error ( ) ) ;
230+ }
231+
232+ self . timeout = read;
233+ Ok ( ( ) )
234+ }
202235}
203236
204237impl Drop for COMPort {
@@ -316,31 +349,19 @@ impl io::Write for COMPort {
316349}
317350
318351impl SerialPort for COMPort {
352+ #[ inline]
319353 fn name ( & self ) -> Option < String > {
320354 self . port_name . clone ( )
321355 }
322356
357+ #[ inline]
323358 fn timeout ( & self ) -> Duration {
324359 self . timeout
325360 }
326361
362+ #[ inline]
327363 fn set_timeout ( & mut self , timeout : Duration ) -> Result < ( ) > {
328- let milliseconds = timeout. as_secs ( ) * 1000 + timeout. subsec_nanos ( ) as u64 / 1_000_000 ;
329-
330- let mut timeouts = COMMTIMEOUTS {
331- ReadIntervalTimeout : 0 ,
332- ReadTotalTimeoutMultiplier : 0 ,
333- ReadTotalTimeoutConstant : milliseconds as DWORD ,
334- WriteTotalTimeoutMultiplier : 0 ,
335- WriteTotalTimeoutConstant : 0 ,
336- } ;
337-
338- if unsafe { SetCommTimeouts ( self . handle , & mut timeouts) } == 0 {
339- return Err ( super :: error:: last_os_error ( ) ) ;
340- }
341-
342- self . timeout = timeout;
343- Ok ( ( ) )
364+ self . set_timeouts ( Duration :: from_secs ( 0 ) , timeout, Duration :: from_secs ( 0 ) )
344365 }
345366
346367 fn write_request_to_send ( & mut self , level : bool ) -> Result < ( ) > {
0 commit comments