+ struct pollfd *pollfd;
+ int i,j;
+ int num_rdy, num_hup;
+ int high_prio;
+ int ret;
+
+ if(fd_pairs->num_pairs <= 0) {
+ printf("No channel to read\n");
+ goto end;
+ }
+
+ /* Get the subbuf sizes and number */
+
+ for(i=0;i<fd_pairs->num_pairs;i++) {
+ struct fd_pair *pair = &fd_pairs->pair[i];
+
+ ret = ioctl(pair->channel, RELAYFS_GET_N_SUBBUFS,
+ &pair->n_subbufs);
+ if(ret != 0) {
+ perror("Error in getting the number of subbuffers");
+ goto end;
+ }
+ ret = ioctl(pair->channel, RELAYFS_GET_SUBBUF_SIZE,
+ &pair->subbuf_size);
+ if(ret != 0) {
+ perror("Error in getting the size of the subbuffers");
+ goto end;
+ }
+ }
+
+ /* Mmap each FD */
+ for(i=0;i<fd_pairs->num_pairs;i++) {
+ struct fd_pair *pair = &fd_pairs->pair[i];
+
+ pair->mmap = mmap(0, pair->subbuf_size * pair->n_subbufs, PROT_READ,
+ MAP_SHARED, pair->channel, 0);
+ if(pair->mmap == MAP_FAILED) {
+ perror("Mmap error");
+ goto munmap;
+ }
+ }
+
+
+ /* Start polling the FD */
+
+ pollfd = malloc(fd_pairs->num_pairs * sizeof(struct pollfd));
+
+ /* Note : index in pollfd is the same index as fd_pair->pair */
+ for(i=0;i<fd_pairs->num_pairs;i++) {
+ pollfd[i].fd = fd_pairs->pair[i].channel;
+ pollfd[i].events = POLLIN|POLLPRI;
+ }
+
+ /* Signal the parent that ready for IO */
+ if(sig_parent) kill(getppid(), SIGIO);
+
+ while(1) {
+ high_prio = 0;
+ num_hup = 0;
+#ifdef DEBUG
+ printf("Press a key for next poll...\n");
+ char buf[1];
+ read(STDIN_FILENO, &buf, 1);
+ printf("Next poll (polling %d fd) :\n", fd_pairs->num_pairs);
+#endif //DEBUG
+
+ /* Have we received a signal ? */
+ if(quit_program) break;
+
+ num_rdy = poll(pollfd, fd_pairs->num_pairs, -1);
+ if(num_rdy == -1) {
+ perror("Poll error");
+ goto free_fd;
+ }
+
+ printf("Data received\n");
+
+ for(i=0;i<fd_pairs->num_pairs;i++) {
+ switch(pollfd[i].revents) {
+ case POLLERR:
+ printf("Error returned in polling fd %d.\n", pollfd[i].fd);
+ num_hup++;
+ break;
+ case POLLHUP:
+ printf("Polling fd %d tells it has hung up.\n", pollfd[i].fd);
+ num_hup++;
+ break;
+ case POLLNVAL:
+ printf("Polling fd %d tells fd is not open.\n", pollfd[i].fd);
+ num_hup++;
+ break;
+ case POLLPRI:
+ printf("Urgent read on fd %d\n", pollfd[i].fd);
+ /* Take care of high priority channels first. */
+ high_prio = 1;
+ ret |= read_subbuffer(&fd_pairs->pair[i]);
+ break;
+ }
+ }
+ /* If every FD has hung up, we end the read loop here */
+ if(num_hup == fd_pairs->num_pairs) break;
+
+ if(!high_prio) {
+ for(i=0;i<fd_pairs->num_pairs;i++) {
+ switch(pollfd[i].revents) {
+ case POLLIN:
+ /* Take care of low priority channels. */
+ printf("Normal read on fd %d\n", pollfd[i].fd);
+ ret |= read_subbuffer(&fd_pairs->pair[i]);
+ break;
+ }
+ }
+ }
+
+ }
+
+free_fd:
+ free(pollfd);
+
+ /* munmap only the successfully mmapped indexes */
+ i = fd_pairs->num_pairs;
+munmap:
+ /* Munmap each FD */
+ for(j=0;j<i;j++) {
+ struct fd_pair *pair = &fd_pairs->pair[j];
+ int err_ret;
+
+ err_ret = munmap(pair->mmap, pair->subbuf_size * pair->n_subbufs);
+ if(err_ret != 0) {
+ perror("Error in munmap");
+ }
+ ret |= err_ret;
+ }
+
+end:
+ return ret;