From 1eb83b31aca47746401567d6003d6a69cc6447cb Mon Sep 17 00:00:00 2001 From: Lars Christensen Date: Wed, 1 Feb 2023 23:09:33 +0100 Subject: [PATCH] Set Windows timeouts to enforce non-blocking read Settings ReadIntervalTimeout and ReadTotalTimeoutMultiplier to MAXDWORD in the COMMTIMEOUTS structure on Windows makes Windows behave as normally expected; a read call to the serial port will return immediately if there is any data available, or if a single byte arrives in the buffer. If no data arrives, it will timeout out after the timeout specified in ReadTotalTimeoutConstant. This fixes issues where reading from a serial port would take longer than desired when less data arrives that there is room for in the buffer passed to the read function. See also: https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-commtimeouts --- src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1d7f213..bdee736 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -803,17 +803,18 @@ mod sys { #[cfg(windows)] mod sys { + use winapi::um::winnt::MAXDWORD; + use super::os_prelude::*; use super::StdIoResult; /// Overrides timeout value set by serialport-rs so that the read end will /// never wake up with 0-byte payload. pub(crate) fn override_comm_timeouts(handle: RawHandle) -> StdIoResult<()> { let mut timeouts = COMMTIMEOUTS { - // wait at most 1ms between two bytes (0 means no timeout) - ReadIntervalTimeout: 1, - // disable "total" timeout to wait at least 1 byte forever - ReadTotalTimeoutMultiplier: 0, - ReadTotalTimeoutConstant: 0, + // Enable POSIX-like behaviour to wait for ANY about of bytes or timeout + ReadIntervalTimeout: MAXDWORD, + ReadTotalTimeoutMultiplier: MAXDWORD, + ReadTotalTimeoutConstant: 1, // write timeouts are just copied from serialport-rs WriteTotalTimeoutMultiplier: 0, WriteTotalTimeoutConstant: 0,