Skip to content
Advertisement

Using linux epoll: epoll_ctl seems to have redundant parameter?

Usually on linux when we wish to use epoll, we first create a epfd, and then register fd and events to it.

 int fd=open(...)
 int epfd=epoll_create(1);
 epoll_event ev,events[1];
 ev.data.fd=fd;//already registered
 ev.events=EPOLLIN|EPOLLET;
 epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);//still need to specify fd?

Above is a common example I found from internet. It works, but problem is:

  1. ev.data.fd=fd here I already have my “fd” assigned to ev structure.

  2. epoll_ctl still requires the 3rd parameter of this fd.

While the 4th parameter of epoll_ctl already contain information about this fd. This is why I think it’s redundant.

Any explanations?

Advertisement

Answer

Your ev.data is a union. You can use the fd member, but you don’t have to. You can also stick other data in there.

The point of ev.data is of course that that‘s the data you get back when the event fires, so you need some way of relating that to the original file descriptor. Writing that very file descriptor into the fd variant is one simple way to achieve that, but other solutions exist.

One popular example is to define an abstract class Fd, derive concrete classes from it for particular purposes, and then write the upcast base pointer, converted to void*, into ev.data.ptr. On receipt of the event, you cast ev.data.ptr back to Fd* and invoke a suitable virtual member function to handle the event.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement