Prevent blocking all virtual serial ports on full PTS #16
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I am running the following command to multiplex a serial port into multiple virtual serial ports:
The intention is for
/dev/gps0_gpsd
and/dev/gps0_data
to be actively read from during normal operations, and/dev/gps0_debug
should just be available in case I want to monitor the GPS data or send commands to it.This works well for a few seconds, but after some time
vsp-router
blocks on trying to write togps0_debug
which is not actively being read from. When this happens new data stop being sent to all virtual serial ports, including the ones that are actively being read from.This is due to the fact that data written to a PTS are being buffered until around ~20kB of data (enforced by the kernel), then new writes are blocked by the kernel until some data is read.
When reading again from
gps0_debug
data streaming resumes on all virtual serial ports, andvsp-router
also proceeds to send all data that was accumulated during the block to all virtual serial ports.This is causing me some issues:
I address those issues in this PR: when a virtual serial port is not being read from, up to ~20kB of data will be accumulated and they will be returned at the next read. New data past those ~20kB will be discarded with a warning message in the logs, but without blocking the other virtual serial ports.
When reading from a virtual serial port, up to ~20kB of stale data will be returned, followed by new data. This behavior is different from a physical serial port which does not buffer data, but it is easy to control from services opening the virtual serial ports by running
tcflush
with the queue selectorTCIFLUSH
on the file descriptor corresponding to the virtual serial port before attempting to read data from it. This way only new data will be returned, the buffered data will be discarded.For example
gpsd
correctly does atcflush
when opening serial ports.Applying this PR to
vsp-router
and doing thetcflush
from client services results in reads from virtual serial ports behaving as close as possible as reads from physical serial ports. I suggest adding this information abouttcflush
somewhere as it is really useful when combined withvsp-router
.Note that I am very new at Rust, feel free to rewrite the code as you see fit if you want to accept this PR.