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_set
s 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();
}
}