2009-02-26 1 views
3

Ich habe versucht, eine Reihe von Named-Pipes für eine Weile jetzt abzufragen, und ich bekomme eine sofortige Antwort von POLLNVAL auf jeden named Pipe-Datei-Deskriptor. Nach dem Auffinden dieser blog post about broken polling in OS X bin ich mir ziemlich sicher, dass dies ein Fehler in OS X ist.Es sieht wirklich so aus, als ob OS X einen Fehler hat, wenn poll() auf einer Named Pipe (FIFO) verwendet wird ... kann ein Experte bestätigen?

Ich bin bereits dabei, meinen Code auf die Verwendung von UDP-Sockets zu wechseln, aber ich wollte SO zur Verifizierung über dieses a) so fragen dass ich sicher bin, dass es wirklich kaputt ist und b) zu Dokumentationszwecken.

Hier ist eine abgespeckte Version des Codes Ich schrieb (obwohl der Code in dem obigen Link, die ich getestet, es ist ziemlich gut formuliert):

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

diese Ausgänge:

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

bis zum Überdruss.

Irgendjemand sonst rannte in das? Das ist ein echter Fehler, oder?

Antwort

3

Dies scheint ein echter Fehler zu sein. Es funktioniert wie erwartet auf Linux und OpenBSD und schlägt fehl, wie Sie auf OS X beschreiben.

3

OSX 10.4.1, kann ich das Verhalten bestätigen. Derselbe Code funktioniert (solange Timeout-Nachrichten in Ordnung sind) unter Linux. Alle Beweise, einschließlich dieser - http://www.virtualbox.de/changeset/12347 - deutet darauf hin, dass es ein echtes Problem gibt.

+0

Timeouts sind korrektes Verhalten ohne Schreiber. Ich schrieb ein einfaches Schreiberprogramm für weitere Tests und das Programm in der Q liest den FIFO gut auf Linx/OpenBSD und versagt kläglich auf OS X (dasselbe POLLNVAL-Problem). – dwc

1

Yup, bekannter Fehler. Ich denke der Pollbruch ist erst seit 10.4, wir mussten uns in Fink damit beschäftigen. Glib's configure.in hat einen Test dafür, also können Sie sicher sein, dass Sie es sich nicht vorstellen. (Nun, nicht genau das, Glib-Tests für die Abstimmung auf Geräten, nicht Fifos.)

Verwandte Themen