How to pass a callback function pointer to epoll_event structure in C++

被刻印的时光 ゝ 提交于 2020-01-16 18:12:06

问题


I have been searching an answer for this question and I came across the functions timerfd_create and epollin Linux. In a tutorial it was said that epoll_ctl() has an epoll_data_t union member of the epoll_event structure which can be used to execute a callback function on a timerfd event firing. But I am not sure on how to do it. Can anyone please help.


回答1:


You can't put a callback function pointer into epoll_event because it can't fit in any of these slots:

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

What you could do instead is store the timer fd in the epoll_event and check to see if that's the one that fires:

epoll_event ev;
ev.data.fd = timerfd;

epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &ev); 

With that setup, then when we call epoll_wait, we can check to see if the event that fired was for timerfd:

int n = epoll_wait (epollfd, events , num_events, -1 ); 
for (int i = 0; i < n; ++i) {
    if (events[i].data.fd == timerfd) {
        handle_timer_callback();
    }
    else {
        // something else
    }
}

Alternatively, if you're open to giving up some performance, you can just create a complete object hierarchy for events:

class EventHandler {
public:
    virtual ~EventHandler() = default;
    virtual int fd() const = 0;
    virtual void fire() = 0;
};

You can store an EventHandler* into ptr:

EventHandler* handler = new TimerHandler();
ev.data.ptr = handler;
epoll_ctl(epollfd, EPOLL_CTL_ADD, handler->fd(), &ev);

And that way, if everything we put into epoll is an EventHandler:

int n = epoll_wait (epollfd, events , num_events, -1 ); 
for (int i = 0; i < n; ++i) {
    static_cast<EventHandler*>(events[i].data.ptr)->fire();
}


来源:https://stackoverflow.com/questions/28446631/how-to-pass-a-callback-function-pointer-to-epoll-event-structure-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!