3

In the example:

event.events = EPOLLIN;
event.data.fd = fd;

int ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event.data.fd, &event);

I pass the file descriptor in as both a member of event.data and as an argument in its own right.

What does epoll_ctl need the file descriptor twice?

fadedbee
  • 42,671
  • 44
  • 178
  • 308

2 Answers2

3

This is a duplicate of about epoll_ctl()

The reason it needs it twice is that data inside event is a union. epoll_ctl does not know whether you actually provided a file descriptor or something else.

typedef union epoll_data {
    void        *ptr;
    int          fd;
    uint32_t     u32;
    uint64_t     u64;
} epoll_data_t;
Simpl
  • 1,938
  • 1
  • 10
  • 21
0

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)

Where:

epfd is the file descriptor returned by epoll_create which identifies the epoll instance in the kernel.

fd is the file descriptor we want to add to the epoll list/interest list.

op refers to the operation to be performed on the file descriptor fd. In general, three operations are supported:

  • Register fd with the epoll instance (EPOLL_CTL_ADD) and get notified about events that occur on fd
  • Delete/deregister fd from the epoll instance. This would mean that the process would no longer get any notifications about events on that file descriptor (EPOLL_CTL_DEL). If a file descriptor has been added to multiple epoll instances, then closing it will remove it from all of the epoll interest lists to which it was added.
  • Modify the events fd is monitoring (EPOLL_CTL_MOD)

event is a pointer to a structure called epoll_event which stores the event we actually want to monitor fd for.

The first field events of the epoll_event structure is a bitmask that indicates which events fd is being monitored for.

Like so, if fd is a socket, we might want to monitor it for the arrival of new data on the socket buffer (EPOLLIN). We might also want to monitor fd for edge-triggered notifications which is done by OR-ing EPOLLET with EPOLLIN. We might also want to monitor fd for the occurrence of a registered event but only once and stop monitoring fd for subsequent occurrences of that event. This can be accomplished by OR-ing the other flags (EPOLLET, EPOLLIN) we want to set for descriptor fd with the flag for only-once notification delivery EPOLLONESHOT. All possible flags can be found in the man page.

The second field of the epoll_event struct is a union field.

Source

Added some extra data apart from just what was asked for context.

Hope this helps!

89f3a1c
  • 1,430
  • 1
  • 14
  • 24