Quimby
Quimby

Reputation: 19113

Is poll(2) guaranteed to work with duplicated file descriptors?

I use poll(2) extensively for multiplexing I/O which allows me to have a single function per thread collecting all filled pollfd entries from the workers, polling them and returning the entries back to the workers for processing. All other IO calls are non-blocking.

This works really nicely but as I am expanding the workers, it would simplify my work if some pollfd entries could contain the same file descriptor twice or more, perhaps with the same set of expected events or not. But I did not find any guarantees or warnings whether poll can handle this.

So, can poll handle entries with duplicated file descriptor with possibly the same/different set of events? For example

struct pollfd entries[]={{fd,POLLIN,0},{fd,POLLOUT,0},{fd,POLLIN|POLLOUT,0}};
#include <poll.h>
#include <stdio.h>
#include <assert.h>

int main() {
    int fd = 0;
    struct pollfd entries[] = {
        {fd, POLLIN, 0}, {fd, POLLOUT, 0}, {fd, POLLIN | POLLOUT, 0}};

    if( /* FD is writeable */1)
    {
        // No errors for simplicty
        // POLLOUT not queried -> not filled.
        assert(entries[0].revents == 0);
        // POLLOUT queried -> filled.
        assert(entries[1].revents == POLLOUT);
        // POLLOUT queried again -> filled AGAIN. THIS MUST WORK
        assert(entries[2].revents == POLLOUT);
    }
    if( /* FD is readable */1)
    {
        // No errors for simplicty

        // POLLIN queried -> filled.
        assert(entries[0].revents == POLLIN);
        // POLLIN not queried -> not filled.
        assert(entries[1].revents == 0);
        // POLLIN queried again -> filled AGAIN. THIS MUST WORK.
        assert(entries[2].revents == POLLIN);
    }
}

The case I have to avoid is that only some entries are filled by poll, e.g. only entries[1] has POLLOUT in revents but not entries[2].

What about epoll?

Upvotes: 0

Views: 743

Answers (1)

KamilCuk
KamilCuk

Reputation: 140990

I believe this is at best unspecified. If you are creating an application, you should not depend on the behavior of that when an event is received, all revents will have it set.

Note, that when poll returns something in revent, the actual state may potentially change between the end of the call to poll and your call to anything else. So even if you have POLLIN, there may be nothing to be read.

Is poll(2) guaranteed to work with duplicated file descriptors?

Sure.

If fd is writeable will all entries with POLLOUT in events have POLLOUT in revents?

If fd is readable, ... POLLIN...?

Will any errors on fd show on all entries with that fd?

It is guaranteed that at least one revents will be set with the event.

Will poll return the true number of active entries?

Poll will return how many it has set.

Will poll itself not return any errors?

No.

What about epoll?

It's not POSIX. I believe the above also counts for epoll, as I did not find any guarantee in the documentation.

Upvotes: 1

Related Questions