Эполл сокета: EPOLL_CTL_MOD сбросит граничный триггер?

Начните с добавления сокета в набор epoll для чтения по триггеру:

epoll_event ev = {};
ev.data.fd = sock;
ev.events = EPOLLIN | EPOLLET;   // edge triggered reading
epoll_ctl(efd, EPOLL_CTL_ADD, sock, &ev);

Теперь ждите данных:

result = epoll_wait(efd, events, sizeEvents, timeoutMilliseconds);

Гипотетически, скажем, было доступно более 20 байтов данных. Но последующий код хочет проанализировать сообщения из потока в 10-байтовые куски:

result = recv(sock, buffer, 10, 0);

Итак, на данный момент, вы, вероятно, говорите, "если он призывает epoll_waitего код может зависнуть или прерваться даже при наличии оставшихся 10 байтов в потоке сокетов, которые еще предстоит прочитать."И вы были бы правы.

Но вместо того, чтобы возвращаться к epoll_wait, мой код фактически переключает флаги epoll, чтобы он мог функционировать для отправки ответа обратно в тот же сокет.

ev.data.fd = sock;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);

Обратите внимание, что EPOLLIN больше не установлен. Затем код делает стандартный цикл send а также epoll_wait пока полный ответ не будет отправлен.

Когда ответ на сообщение установлен, код возвращается к чтению в режиме запуска по фронту:

 ev.data.fd = sock;
 ev.events = EPOLLIN | EPOLLET;
 epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);

Затем следует ожидание:

 result = epoll_wait(efd, events, sizeEvents, timeoutMilliseconds);    

Теперь при условии, что никаких дополнительных данных не поступило sock так как последний считал сокет, делает выше epoll_wait зависание (или тайм-аут), поскольку уровень фронта не изменился? Или тот факт, что EPOLLIN был выключен и включен, позволяет сбросить граничное состояние так, чтобы epoll_wait вызов вернется немедленно, чтобы указать данные, доступные на сокете?

0 ответов

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