2009-02-26 4 views
3

Je tente depuis un certain temps d'interroger un ensemble de tubes nommés et je reçois toujours une réponse immédiate de POLLNVAL sur n'importe quel descripteur de fichier de canal nommé. Après avoir trouvé ce blog post about broken polling in OS X je suis assez certain qu'il s'agit d'un bug d'OS X.On dirait que OS X a un bug lors de l'utilisation de poll() sur un tube nommé (FIFO) ... un expert peut-il confirmer?

Je prévois déjà de passer mon code à l'aide de sockets UDP, mais je voulais demander SO pour vérification à ce sujet a) que je suis sûr que c'est vraiment cassé, et b) à des fins de documentation.

Voici une version dépouillée du code que j'ai écrit (bien que le code dans le lien ci-dessus, je l'ai testé, il explique assez bien):

#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; 
} 

cette sortie:

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

ad nauseam.

Quelqu'un d'autre est-il confronté à cela? C'est un vrai bug, n'est-ce pas?

Répondre

3

Cela semble être un véritable bug. Il fonctionne comme prévu sur Linux et OpenBSD et échoue comme vous le décrivez sur OS X.

3

OSX 10.4.1, je peux confirmer le comportement. Le même code fonctionne correctement (tant que les messages de délai d'attente sont corrects) sous Linux. Toutes les preuves, y compris celle-ci - http://www.virtualbox.de/changeset/12347 - suggèrent qu'il y a un vrai problème.

+0

Les délais d'attente sont un comportement correct sans écriture. J'ai écrit un programme d'écriture simple pour d'autres tests et le programme dans le Q lit l'amende FIFO sur Linx/OpenBSD et échoue misérablement sur OS X (même problème POLLNVAL). – dwc

1

Yup, bug connu. Je pense que la cassure du vote est seulement depuis 10.4, nous avons dû faire face à cela dans Fink. Le configure.in de Glib a un test pour cela, donc vous pouvez être sûr que vous ne l'imaginez pas. (Eh bien, pas exactement cela, glib teste pour le sondage sur les périphériques, pas fifos.)

Questions connexes