Как передать указатель на функцию обратного вызова в структуру epoll_event в Stack Overflow

Я искал ответ для этот вопрос и я наткнулся на функции timerfd_create а также epollв линуксе В учебнике было сказано, что epoll_ctl() имеет epoll_data_t член профсоюза epoll_event структура, которая может быть использована для выполнения callback функция на timerfd стрельба события. Но я не уверен, как это сделать. Может кто-нибудь, пожалуйста, помогите.

0

Решение

Вы не можете поместить указатель на функцию обратного вызова в epoll_event потому что он не может поместиться ни в один из следующих слотов:

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

Вместо этого вы можете сохранить таймер fd в epoll_event и проверьте, запускает ли это:

epoll_event ev;
ev.data.fd = timerfd;

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

С этой настройкой, то когда мы позвоним epoll_waitмы можем проверить, если event это было сделано для 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
}
}

В качестве альтернативы, если вы готовы отказаться от некоторой производительности, вы можете просто создать полную иерархию объектов для событий:

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

Вы можете хранить EventHandler* в ptr:

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

И таким образом, если все мы вкладываем в epoll является 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();
}
3

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector