Работа с сокетом прослушивания от epoll

Все ниже от man epoll страница:

Функция do_use_fd() использует новый готовый дескриптор файла, пока EAGAIN не будет возвращен read(2) или write(2).

Пример кода для срабатывания ET:

   for(;;) {
       nfds = epoll_wait(kdpfd, events, maxevents, -1);

       for(n = 0; n < nfds; ++n) {
           if(events[n].data.fd == listener) {
               client = accept(listener, (struct sockaddr *) &local,
                               &addrlen);
               if(client < 0){
                   perror("accept");
                   continue;
               }
               setnonblocking(client);
               ev.events = EPOLLIN | EPOLLET;
               ev.events = EPOLLIN | EPOLLET;
               ev.data.fd = client;
               if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {
                   fprintf(stderr, "epoll set insertion error: fd=%d\n",
                           client);
                   return -1;
               }
           }
           else
               do_use_fd(events[n].data.fd);
       }
   }

Таким образом, для read/write операция, мы должны сделать это, зацикливание до EAGAIN получил, но почему это не так для accept?

ИМО, приведенный выше код пропустит некоторые запросы, когда есть несколько клиентских сокетов, ожидающих принятия, так как он принимает только 1 клиентский сокет, мы также должны заключить его в цикл до EAGAIN получено.

Или, может быть, мне чего-то не хватает?

1 ответ

Решение

Посмотрите, как сокет слушателя добавляется к epollfd:

ev.events = EPOLLIN;       // this is the crucial bit
ev.data.fd = listen_sock;

Он не добавляется в триггерном режиме, он добавляется в триггерном уровне. Так что нет необходимости в петле, пока EAGAIN на этом.

Другие вопросы по тегам