You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am using serial-rs on Linux (both Ubuntu and OpenWRT), so this mostly only applies to serial-unix.
I use the Calloop event loop for event-driven systems. Under the hood (on Linux), Calloop basically uses epoll() with whatever file descriptors it extracts from things that implement AsRawFd. The general contract of epoll() in edge-triggered mode (which is what I tend to use) is:
wait until epoll_await() tells you to write
try to write N bytes from a buffer
keep trying this until write() returns -1 and errno is EAGAIN
go back to epoll_await()
This relies on the fd being opened in non-blocking mode. In blocking mode, you will never get EAGAIN, write() will simply block until all bytes are written.
So for example, if I try to write N bytes from a buffer, this call eventually comes down to your implementation of io::Write. You call ppoll() with the timeout and then attempt the write. But even if the timeout is zero, the write will potentially block until all bytes are written.
The workaround we have for this at the moment is to write one byte at a time. That way any time spent blocking on write() is quite short and potentially, but not always, detected beforehand by ppoll().
Versions: Rust 1.53, serial 0.4.0,
Tried on: Ubuntu 20.10 and 21.04, OpenWRT (ramips + musl).
The text was updated successfully, but these errors were encountered:
I am using
serial-rs
on Linux (both Ubuntu and OpenWRT), so this mostly only applies toserial-unix
.I use the Calloop event loop for event-driven systems. Under the hood (on Linux), Calloop basically uses
epoll()
with whatever file descriptors it extracts from things that implementAsRawFd
. The general contract ofepoll()
in edge-triggered mode (which is what I tend to use) is:epoll_await()
tells you to writewrite()
returns-1
and errno isEAGAIN
epoll_await()
This relies on the fd being opened in non-blocking mode. In blocking mode, you will never get
EAGAIN
,write()
will simply block until all bytes are written.In
tty.rs
you do indeed open the fd as non-blocking. But very shortly after, you clear this flag. This makes it impossible to useserial
and enjoy non-blocking writes.So for example, if I try to write N bytes from a buffer, this call eventually comes down to your implementation of
io::Write
. You callppoll()
with the timeout and then attempt the write. But even if the timeout is zero, the write will potentially block until all bytes are written.The workaround we have for this at the moment is to write one byte at a time. That way any time spent blocking on
write()
is quite short and potentially, but not always, detected beforehand byppoll()
.Versions: Rust 1.53, serial 0.4.0,
Tried on: Ubuntu 20.10 and 21.04, OpenWRT (ramips + musl).
The text was updated successfully, but these errors were encountered: