2 * Event loop with file descriptor polling
4 * Copyright 2012 IBM, Corp.
5 * Copyright 2012 Red Hat, Inc. and/or its affiliates
8 * Stefan Hajnoczi <stefanha@redhat.com>
10 * This work is licensed under the terms of the GNU GPL, version 2 or later.
11 * See the COPYING file in the top-level directory.
15 #include <sys/epoll.h>
16 #include "hw/dataplane/event-poll.h"
18 /* Add an event notifier and its callback for polling */
19 void event_poll_add(EventPoll
*poll
, EventHandler
*handler
,
20 EventNotifier
*notifier
, EventCallback
*callback
)
22 struct epoll_event event
= {
26 handler
->notifier
= notifier
;
27 handler
->callback
= callback
;
28 if (epoll_ctl(poll
->epoll_fd
, EPOLL_CTL_ADD
,
29 event_notifier_get_fd(notifier
), &event
) != 0) {
30 fprintf(stderr
, "failed to add event handler to epoll: %m\n");
35 /* Event callback for stopping event_poll() */
36 static void handle_stop(EventHandler
*handler
)
41 void event_poll_init(EventPoll
*poll
)
43 /* Create epoll file descriptor */
44 poll
->epoll_fd
= epoll_create1(EPOLL_CLOEXEC
);
45 if (poll
->epoll_fd
< 0) {
46 fprintf(stderr
, "epoll_create1 failed: %m\n");
50 /* Set up stop notifier */
51 if (event_notifier_init(&poll
->stop_notifier
, 0) < 0) {
52 fprintf(stderr
, "failed to init stop notifier\n");
55 event_poll_add(poll
, &poll
->stop_handler
,
56 &poll
->stop_notifier
, handle_stop
);
59 void event_poll_cleanup(EventPoll
*poll
)
61 event_notifier_cleanup(&poll
->stop_notifier
);
62 close(poll
->epoll_fd
);
66 /* Block until the next event and invoke its callback */
67 void event_poll(EventPoll
*poll
)
69 EventHandler
*handler
;
70 struct epoll_event event
;
73 /* Wait for the next event. Only do one event per call to keep the
74 * function simple, this could be changed later. */
76 nevents
= epoll_wait(poll
->epoll_fd
, &event
, 1, -1);
77 } while (nevents
< 0 && errno
== EINTR
);
78 if (unlikely(nevents
!= 1)) {
79 fprintf(stderr
, "epoll_wait failed: %m\n");
80 exit(1); /* should never happen */
83 /* Find out which event handler has become active */
84 handler
= event
.data
.ptr
;
86 /* Clear the eventfd */
87 event_notifier_test_and_clear(handler
->notifier
);
89 /* Handle the event */
90 handler
->callback(handler
);
95 * This function can be used from another thread.
97 void event_poll_notify(EventPoll
*poll
)
99 event_notifier_set(&poll
->stop_notifier
);