How to poll without clearing the stream that is being polled?

Hello,

So Im trying to read from a stream, but only when there is something present.
So the program I want in pseudocode is

if (something_is_inside_stream) {
    const packet = parsePacketFromReader(stream.reader());
    something.doStuff(packet);
}

Now the problem I am facing is, that when I try to use std.io.poll, it transfers the streams contents to its fifo and reading from the fifo will not request more data when its empty, which is a problem because at the time of reading the packet is sometimes only half arrived.

Now my hope is that that std.posix.poll will just give me information about if there is something in stream and that just reading from there will just block and deliver new data until the packet has fully arrived.

The problem: I dont know how to use std.posix.poll

Allocate an array of pollfd, set the file handle fd, set zero to revents, and set the flag for the desired polling events to events. Finally call poll with a milliseconds timeout.

Example:

var polls: [1]std.posix.pollfd = undefined;
polls[0] = .{
        .fd = std.io.getStdIn(),
        .events = std.posix.POLL.IN,
        .revents = 0,
};
// -1 means infinite/no timeout
_ = try posix.poll(polls, -1);
5 Likes

Thank you so much, I think in the future I should remember that linux man pages are my friend

4 Likes

Exactly!!! When learning languages like C or Zig it is absolutely necessary (IMHO) to study OS API, be it POSIX poll(), Linux specific epoll or Windows API.

As to poll - be aware of spurious POLLIN, from man 2 poll:

See the discussion of spurious readiness notifications under the BUGS section of select (2)

You have two options to deal with this

  • make fd non-blocking and check for EWOULDBLOCK/EAGAIN
  • ask OS how many bytes are really there (with ioctl(FIONREAD)) before read()ing
1 Like

Yep, especially in zig they are really amazing because the posix api also works for windows in literally every use case ive had before

granted i havent used windows in the last 3 or 4 years but at least that seem to have an implementation for the windows case