• why epoll_wait delivers events more than once in ET mode on stdin

    From chenstrace@21:1/5 to All on Thu Jun 14 23:10:32 2018
    As my expection, the following test code should only return from epoll_wait once, just like man page of epoll said:

    "edge-triggered mode delivers events only when changes occur on the monitored file descriptor"


    But in fact, the epoll_wait returned more than once, why?



    #include <stdio.h>
    #include <sys/epoll.h>
    #include <string.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <limits.h>
    #define MAX_EVENTS 512

    static char* get_epoll_events_str(uint32_t event);

    int main(int argc, char *argv[]) {
    int i,nfds;
    struct epoll_event event;
    struct epoll_event events[MAX_EVENTS];
    int fd = STDIN_FILENO;
    int epfd = epoll_create1(0);
    if (epfd == -1) {
    perror("epoll_create1");
    exit(EXIT_FAILURE);
    }

    event.events = EPOLLOUT | EPOLLET;
    event.data.u64 = 123;
    int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);
    if (ret == -1) {
    perror("epoll_ctl");
    exit(EXIT_FAILURE);
    }
    while (1) {
    nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);
    if (nfds == -1) {
    perror("epoll_wait");
    exit(EXIT_FAILURE);
    }
    printf("epoll_wait return %d\n", nfds);

    for (i = 0; i < nfds; i++) {
    char* str = get_epoll_events_str(events[i].events);
    printf("%dth fd's data.u64=%lu,event is %s\n",i,events[i].data.u64,str);
    free(str);
    }
    sleep(1);
    }
    return 0;
    }

    static char* get_epoll_events_str(uint32_t event) {
    char str[4096] = {0};

    if(event == 0)
    {
    return NULL;
    }

    if (event & EPOLLIN) strcat(str, "EPOLLIN,");
    if (event & EPOLLPRI) strcat(str, "EPOLLPRI,");
    if (event & EPOLLOUT) strcat(str, "EPOLLOUT,");
    if (event & EPOLLRDNORM) strcat(str, "EPOLLRDNORM,");
    if (event & EPOLLRDBAND) strcat(str, "EPOLLRDBAND,");
    if (event & EPOLLWRNORM) strcat(str, "EPOLLWRNORM,");
    if (event & EPOLLWRBAND) strcat(str, "EPOLLWRBAND,");
    if (event & EPOLLMSG) strcat(str, "EPOLLMSG,");
    if (event & EPOLLERR) strcat(str, "EPOLLERR,");
    if (event & EPOLLHUP) strcat(str, "EPOLLHUP,");
    if (event & EPOLLRDHUP) strcat(str, "EPOLLRDHUP,");
    if (event & EPOLLWAKEUP) strcat(str, "EPOLLWAKEUP,");
    if (event & EPOLLONESHOT) strcat(str, "EPOLLONESHOT,");
    if (event & EPOLLET) strcat(str, "EPOLLET,");

    if(strlen(str) == 0)
    {
    return NULL;
    }

    return strdup(str);
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rainer Weikusat@21:1/5 to chenstrace on Fri Jun 15 13:15:33 2018
    chenstrace <k54765254@gmail.com> writes:
    As my expection, the following test code should only return from epoll_wait once, just like man page of epoll said:

    "edge-triggered mode delivers events only when changes occur on the monitored file descriptor"


    But in fact, the epoll_wait returned more than once, why?

    [please see original for code]

    It shouldn't return at all weren't it for the fact that stdin and stdout
    refer to the same terminal device: You'll get a notification whenever
    an output operation completes and since you keep printing message to
    same (virtual) device, the program feeds itself with events.

    It's possible to demonstrate this by opening three shell windows and determining the terminal device used for each. If there are only these
    three, they should usually be /dev/pts/0, /dev/pts/1 and /dev/pts/2[*].

    The program can be started with stdin connect to the second pty via

    ./a.out <>/dev/pts/1

    If you now go to the third terminal and print to the pty of the second
    terminal session, eg, via

    echo dumdideldu >/dev/pts/1

    you'll get an epoll notification in the program which gets printed to /dev/pts/0 without causing another epoll notification.

    [*] Unless Fedora meanwhile 'fixed' that to make them /rest/4lIE1XES/ved,
    /jump/ved/Pa8Z and /michel/aus/loenneberga for some reason with a very
    elaborate justification which keeps changing in line with what will
    most likely 'sell' to the current target audience.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)