Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read is always non-blocking even when no data is available to read #12

Open
jessebraham opened this issue Feb 7, 2022 · 6 comments · May be fixed by #50 or #185
Open

read is always non-blocking even when no data is available to read #12

jessebraham opened this issue Feb 7, 2022 · 6 comments · May be fixed by #50 or #185
Labels
migrated This issue was migrated from GitLab

Comments

@jessebraham
Copy link
Member

This issue was migrated from GitLab. The original issue can be found here:
https://gitlab.com/susurrus/serialport-rs/-/issues/89

The current behavior of read on an open serial port is that it always returns immediately, even when there is no data available in the input buffer. This may be in contradiction with the understanding here (from tty.rs).

It's also not consistent and not obvious how to make it consistent with the description from https://linux.die.net/man/3/cfmakeraw related to canonical/non-canonical modes. Please note that according to that explanation, raw mode does not guarantee that reads blocks if no data is available. Non-canonical mode with MIN > 0; TIME == 0 or MIN == 0; TIME > 0 or MIN > 0; TIME > 0.

Please clarify what is the intention of serialport-rs implementation, and how to make read block when no data is available for a configurable maximum timeout.

@jessebraham jessebraham added the migrated This issue was migrated from GitLab label Feb 7, 2022
@mlsvrts
Copy link
Contributor

mlsvrts commented Apr 21, 2022

Possibly related to #25

I guess that the current solution for 'wait forever' on read would be:

port.set_timeout(Duration::MAX).ok();

@eranknafo2001
Copy link

At least in posix systems, it is because of this:

    #[cfg(target_os = "linux")]
    let wait_res = {
        let timespec = TimeSpec::milliseconds(milliseconds);
        nix::poll::ppoll(slice::from_mut(&mut fd), Some(timespec), SigSet::empty())
    };
    #[cfg(not(target_os = "linux"))]
    let wait_res = nix::poll::poll(slice::from_mut(&mut fd), milliseconds as nix::libc::c_int);

from the file: src/posix/poll.rs.

In the case of linux systems, the ppoll timeout parameter needs to be None to block without timeout.
In the case of non-linux systems, the poll's timeout parameter needs to be negative to block without timeout.
In both cases the default timeout of the library (0) will cause to always return without blocking.

@mlsvrts
Copy link
Contributor

mlsvrts commented May 4, 2022

@eranknafo2001 Agreed, but I don't think there is any way to express 'no timeout' in serialport-rs (see my comment here) -- so we're left with 'wait for a really long time' as a work-around.

@eranknafo2001 eranknafo2001 linked a pull request May 4, 2022 that will close this issue
@eranknafo2001
Copy link

I created a PR to fix it #50

@DanielJoyce
Copy link

Termios is a layer on top of a raw serial port. I think serial port library should just stick to simple support for serial port, and we can write extensions on top. But we shouldn't complicate serial-port-rs.

@ARizzo35 ARizzo35 linked a pull request May 7, 2024 that will close this issue
@sweet-de-way
Copy link

Termios 是原始串行端口之上的一个层。我认为串口库应该只坚持对串口的简单支持,我们可以在上面写扩展。但我们不应该使 serial-port-rs 复杂化。

Blocking is necessary, but we cannot implement blocking on top of non-blocking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
migrated This issue was migrated from GitLab
Projects
None yet
5 participants