Skip to content

Commit dba08d5

Browse files
committed
Add COM::set_timeouts
1 parent ebe786e commit dba08d5

File tree

1 file changed

+37
-16
lines changed

1 file changed

+37
-16
lines changed

src/windows/com.rs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
2834
struct OverlappedHandle(pub HANDLE);
2935

3036
impl 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

204237
impl Drop for COMPort {
@@ -316,31 +349,19 @@ impl io::Write for COMPort {
316349
}
317350

318351
impl 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

Comments
 (0)