about epoll_ctl()
Asked Answered
S

2

14

when using epoll_ctl(), I found that the third parameter "fd" is another file descriptor besides the epoll file descriptor "epfd". And I saw an example like this:

event.data.fd = sfd; //sfd is a fd for listening
event.events = EPOLLIN | EPOLLET;
s = epoll_ctl (efd, EPOLL_CTL_ADD, sfd, &event);

As I saw, file descriptor in event.data.fd is the same as the third parameter in epoll_ctl, why need to pass this descriptor twice? is there any difference?

Stallworth answered 17/2, 2012 at 9:28 Comment(1)
You may consider the implementation didn't do the assignment for you. Sometimes low level C system call rely on programmers. The event is not always needed, e.g. during EPOLL_CTL_DEL the event is ignored but you cannot give a NULL pointer as argument.Couldst
O
20

Actually you don't have to set event.data.fd. It's a union, you can set other members. When epoll_wait returns you get the event.data associated with the descriptor that became interesting:

typedef union epoll_data {
    void    *ptr;
    int      fd;
    uint32_t u32;
    uint64_t u64;
} epoll_data_t;

Which means you're completely free not to put anything in fd and put something in ptr instead (for example).

In conclusion, epoll_ctl can't rely on the fact you'll fill fd in, that's why it has a separate explicit parameter.

Ophir answered 17/2, 2012 at 9:33 Comment(7)
The fd you pass to epoll_ctl is the file descriptor you wish to get events for. The fd in event.data is strictly for your use -- the system ignores it and you can use it for any purpose.Centime
I've actually seen a lot of code that puts the fd in the epoll_data structure, only to use that fd as an index into a table that holds a pointer to the application's structure associated with that socket -- a structure that also contains the fd. Apparently, they didn't realize they could use the ptr member instead of fd and save the lookup.Centime
OK, I understand --- the fd in epoll_data is not intended to be used by the system but by myself.Stallworth
To clarify, the ev that is epoll_ctl(..ADD..) is "spit back out" when you epoll_wait() and there's an event? @DavidSchwartz i.e., can you "store" the pointers in epoll?Victoriavictorian
@awelotta You can store whatever is useful to you in that union. Using ptr to store a pointer to some object or structure with information about the context is common.Centime
@DavidSchwartz I was just wondering if you risked memory leak if you stored malloc'd pointers (i.e. is it sufficient to just make sure you epoll_wait'd every epoll fd?)Victoriavictorian
@awelotta So long as you free them when you are done with them, there's no risk of a leak.Centime
D
0

I think there is.

This is my test demo.

When using ev.data.fd = STDIN_FILENO

In the terminal, you press the Enter button to end the input and printf “welcome...”

When using ev.data.ptr = stdin

You need to press ctrl+d to end the input and printf “welcome...”

Does it mean that ev.data is not only used for recording?

    int main()
    {
        int epfd, nfds;
        struct epoll_event ev, events[5];
        epfd = epoll_create(1); 
    
        //ev.data.fd = STDIN_FILENO;
        ev.data.ptr = stdin;
        ev.events = EPOLLIN | EPOLLET; 
        epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev); 
    
        for (;;)
        {   
            nfds = epoll_wait(epfd, events, 5, -1);
            for (int i = 0; i < nfds; i++)
            {
                // if (events[i].data.fd == STDIN_FILENO)
                if (events[i].data.ptr == stdin)
                   printf("welcome to epoll's word!\n");
            }
        } 
    }
Diaspore answered 17/1 at 3:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.