0

I have the following code that uses select:

fd_set fdsu;
FD_ZERO(&fdsu);
FD_SET(fd, &fdsu);
fd_set efds = fdsu;
fd_set dfds = fdsu;
while (1) {
    select(cameraUSBP.fd + 1, NULL, &dfds, &efds, NULL);
    if (FD_ISSET(cameraUSBP.fd, &efds)) {
        errorData();
    }
    if (FD_ISSET(cameraUSBP.fd, &dfds)) {
        writeData();
    }
}

I want to port it to use poll:

struct pollfd pollfds[1];
pollfds[0].fd = fd;
pollfds[0].events = POLLIN;
while (1) {
    poll(pollfds, 1, -1);
    //how to insert writeData() and errorData()
}

I'm confused. How do I insert the writeData and errorData events?

Shawn
  • 47,241
  • 3
  • 26
  • 60
gregoiregentil
  • 1,793
  • 1
  • 26
  • 56

1 Answers1

2

First, your select() version has a number of significant errors.

From the linux manpage:

Note well: Upon return, each of the file descriptor sets is modified in place to indicate which file descriptors are currently "ready". Thus, if using select() within a loop, the sets must be reinitialized before each call.

You're not doing that. You also can't portably assign fd_sets like you're doing; it works on some implementations, it doesn't on others (Say, if it's implemented as an array). Nor are you checking to see if select() fails.

It should look like

while (1) {
    fd_set efds, dfds;
    FD_ZERO(&efds);
    FD_SET(cameraUSBP.fd, &efds);
    FD_ZERO(&dfds);
    FD_SET(cameraUSBP.fd, &dfds);
    if (select(cameraUSBP.fd + 1, NULL, &dfds, &efds, NULL) < 0) {
        reportError(errno);
        break; // or exit or whatever
    }
    if (FD_ISSET(cameraUSBP.fd, &efds)) {
        errorData();
    }
    if (FD_ISSET(cameraUSBP.fd, &dfds)) {
        writeData();
    }
}

struct pollfd, on the other hand, has separate fields for events to monitor and events that happened, so it only has to be initialized once if the descriptors you're monitoring never change. You set events to the things you're interested in, using a bitwise or of flags, and check revents to see what happened by doing a bitwise and with the relevant flag.

struct pollfd pollfds[1];
pollfds[0].fd = cameraUSBP.fd;
pollfds[0].events = POLLOUT; // since you want to know when it's writable
while (1) {
    if (poll(pollfds, 1, -1) < 0) {
        reportError(errno);
        break;
    }
    if (pollfds[0].revents & POLLERR) { // Doesn't need to be set in events
        errorData();
    }
    if (pollfds[0].revents & POLLOUT) {
        writeData();
    }
}
Shawn
  • 47,241
  • 3
  • 26
  • 60