Похоже, что в OS X есть ошибка при использовании poll () для именованного канала (FIFO) ... может ли эксперт подтвердить это? - PullRequest
3 голосов
/ 26 февраля 2009

Я уже некоторое время пытаюсь опросить из набора именованных каналов, и я продолжаю получать немедленный ответ POLLNVAL на любой дескриптор файла именованного канала. После нахождения этого сообщения в блоге о неработающем опросе в OS X я почти уверен, что это ошибка b-u-g в OS X.

Я уже планирую переключить свой код на использование UDP-сокетов, но я хотел бы попросить SO о проверке этого а), так что я уверен, что он действительно сломан, и б) в целях документации.

Вот урезанная версия кода, который я написал (хотя код в приведенной выше ссылке, которую я тестировал, довольно хорошо прописан):

#includes
...
....
#

static const char* first_fifo_path = "/tmp/fifo1";
static const char* second_fifo_path = "/tmp/fifo2";

int setup_read_fifo(const char* path){
  int fifo_fd = -1;

  if( mkfifo(path, S_IRWXU | S_IRWXG | S_IRWXO) )
    perror("error calling mkfifo()... already exists?\n");

  if((fifo_fd = open(path, O_RDONLY | O_NDELAY)) < 0)
    perror("error calling open()");

  return fifo_fd;
}

void do_poll(int fd1, int fd2){
  char inbuf[1024];
  int num_fds = 2;
  struct pollfd fds[num_fds];
  int timeout_msecs = 500;

  fds[0].fd = fd1;
  fds[1].fd = fd2;
  fds[0].events = POLLIN;
  fds[1].events = POLLIN;

  int ret;
  while((ret = poll(fds, num_fds, timeout_msecs)) >= 0){
    if(ret < 0){
      printf("Error occured when polling\n");
      printf("ret %d, errno %d\n", ret, errno);
      printf("revents =  %xh : %xh \n\n", fds[0].revents, fds[1].revents);
    }

   if(ret == 0){
      printf("Timeout Occurred\n");
      continue;
    }                                                                   

    for(int i = 0; i< num_fds; i++){
      if(int event = fds[i].revents){

        if(event & POLLHUP)
          printf("Pollhup\n");
        if(event & POLLERR)
          printf("POLLERR\n");
        if(event & POLLNVAL)
          printf("POLLNVAL\n");

        if(event & POLLIN){
          read(fds[i].fd, inbuf, sizeof(inbuf));
          printf("Received: %s", inbuf);
        }
      }
    }
  }
}

int main (int argc, char * const argv[]) {
  do_poll(setup_read_fifo(first_fifo_path), setup_read_fifo(second_fifo_path));
  return 0;
}

это выводит:

$ ./executive 
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
...

до тошноты.

Кто-нибудь еще сталкивался с этим? Это настоящая ошибка, верно?

Ответы [ 3 ]

3 голосов
/ 26 февраля 2009

OSX 10.4.1, могу подтвердить поведение. Тот же код прекрасно работает (если сообщения о тайм-ауте в порядке) в Linux. Все свидетельства, включая это - http://www.virtualbox.de/changeset/12347 - предполагают, что существует реальная проблема.

3 голосов
/ 26 февраля 2009

Это похоже на настоящую ошибку. Он работает должным образом в Linux и OpenBSD и дает сбой, как вы описали в OS X.

1 голос
/ 11 марта 2009

Да, известная ошибка. Я думаю, что разбивка опроса только с 10.4, нам пришлось иметь дело с этим в Fink. У configure.in Glib есть тест для этого, так что вы можете быть уверены, что не представляете себе это. (Ну, не совсем это, тест glib для опроса на устройствах, а не fifos.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...