Start by adding a socket to an epoll set for edge triggered reading:
epoll_event ev = {};
ev.data.fd = sock;
ev.events = EPOLLIN | EPOLLET; // edge triggered reading
epoll_ctl(efd, EPOLL_CTL_ADD, sock, &ev);
Now wait for data:
result = epoll_wait(efd, events, sizeEvents, timeoutMilliseconds);
Hypothetically, let's say there was 20+ bytes of data available. But the subsequent code wants to parse messages off the stream in 10 byte chunks:
result = recv(sock, buffer, 10, 0);
So at this point, you're probably saying, "if he invokes epoll_wait
, his code may hang or timeout even with the remaining 10 bytes in the socket stream that have yet to be read." And you would be correct.
But instead of going back to epoll_wait, my code actually switches epoll flags so it can function for sending a response back on that same socket.
ev.data.fd = sock;
ev.events = EPOLLOUT|EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);
Notice that EPOLLIN is no longer set. Then the code does the standard loop of send
and epoll_wait
until the full response is sent.
When the message response has been set, the code goes back to reading in edge triggered mode:
ev.data.fd = sock;
ev.events = EPOLLIN | EPOLLET;
epoll_ctl(efd, EPOLL_CTL_MOD, sock, &ev);
Followed by a wait:
result = epoll_wait(efd, events, sizeEvents, timeoutMilliseconds);
Now assuming no additional data has arrived on sock
since the last read off the socket, does the above epoll_wait
hang (or timeout) since the edge level hasn't changed? Or does the fact that EPOLLIN was toggled off and on again allow the edge state to be reset such that the above epoll_wait
call would return immediately to indicate data available on the socket?