6

I'm using epoll to get notifications about incoming data. It's not hard because all events returned by epoll_wait() indicates, that I can read data from epoll_event.data.fd (socket descriptor).

But now I want get both types of notification: receiving and sending (socket is available for send). But I can't to do it because:

  1. epoll_event.events which is returned by epoll_wait() is the same as I pass in epoll_ctl(). So it contains both EPOLLIN and EPOLLOUT in my case.
  2. Also if i trying to twice add one socket in epoll (as EPOLLIN and as EPOLLOUT event) I'll get a EEXIST.

How can I solve this problem without manually calling select() every time I get notification?

Nelson Tatius
  • 7,693
  • 8
  • 47
  • 70

2 Answers2

6

man epoll_wait clearly states that "the events member will contain the returned event bit field.". Therefore, if you are getting EPOLLIN | EPOLLOUT in epoll_event.events, then your socket must be ready for both reading and writing.

If you only want to be notified when the socket changes state, use EPOLLET for edge-triggered operation.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
4

When you add a descriptor using epoll_ctl, set the events mask to be EPOLLIN | EPOLLOUT.

When you get notifications via epoll_wait then you'd loop through the returned notifications checking for EPOLLIN and EPOLLOUT.

Pseudo code:

int index, count;
count = epoll_wait(epfd, epoll_event, MAX_EVENTS, -1);
for (index = 0; index < count; ++index) {
  if (epoll_event[index].events & EPOLLIN) {
    // Ready for read
  }

  if (epoll_event[index].events & EPOLLOUT) {
    // Ready for write
  }
}

Some people only set the EPOLLOUT bit when they have data present in their send buffer. I did not include any error checking.

j.w.r
  • 4,136
  • 2
  • 27
  • 29