de-vri-es / serial2-rs

Cross platform serial ports for Rust
Other
41 stars 10 forks source link

read_exact timeout semantics are different from read #31

Closed RossSmyth closed 2 months ago

RossSmyth commented 2 months ago

I've never hit this in any of my programs, but from #17 it made me think about it as a potential pitfall a user could see.

read_exact's timeout semantics are different from read's. Since the implementation of read_exact() is to just call read() in a loop, the timeout is reset each loop, leading to potentially varied timeout lengths between calls. An example:

  1. Set some baud & timeout. Say 9600 bps and 110ms
  2. Call read_exact with 100 bytes. This would mean it would take about 100ms for a full transfer if each byte is contiguous
  3. In the degenerate case, one byte could come every 109ms, leading to the method call hanging for ~11s.

While read instead can only hang for a maximum of 110ms as it will immediately return any bytes in the system's buffer or wait for the immediate next byte.

This may be surprising to some users, I'm not sure. But if should be written somewhere.

de-vri-es commented 2 months ago

Yeah, this is a known limitation, and one I don't think we really should fix: the timeout is for a single syscall, and some operations repeatedly call read() or write().

For me this is expected behaviour.

It is kind-of documented already, but it could be improved:

The timeout set by this function is an upper bound on individual calls to std::io::Read::read(). Other platform specific time-outs may trigger before this timeout does.

It mentions the timeout is for individual calls to read, but it doesn't explicitly mention that some functions perform repeated reads.

de-vri-es commented 2 months ago

Opened #32 to improve the docs. Do you think that solves the issue?

de-vri-es commented 2 months ago

Fixed in #32 and released as v0.2.21!