Эполл сокета: 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
вызов вернется немедленно, чтобы указать данные, доступные на сокете?