2 * event notifier support
4 * Copyright Red Hat, Inc. 2010
7 * Michael S. Tsirkin <mst@redhat.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "qemu/cutils.h"
15 #include "qemu/event_notifier.h"
16 #include "qemu/main-loop.h"
19 #include <sys/eventfd.h>
24 * Initialize @e with existing file descriptor @fd.
25 * @fd must be a genuine eventfd object, emulation with pipe won't do.
27 void event_notifier_init_fd(EventNotifier
*e
, int fd
)
31 e
->initialized
= true;
35 int event_notifier_init(EventNotifier
*e
, int active
)
41 ret
= eventfd(0, EFD_NONBLOCK
| EFD_CLOEXEC
);
47 e
->rfd
= e
->wfd
= ret
;
49 if (errno
!= ENOSYS
) {
52 if (!g_unix_open_pipe(fds
, FD_CLOEXEC
, NULL
)) {
55 if (!g_unix_set_fd_nonblocking(fds
[0], true, NULL
)) {
59 if (!g_unix_set_fd_nonblocking(fds
[1], true, NULL
)) {
66 e
->initialized
= true;
68 event_notifier_set(e
);
78 void event_notifier_cleanup(EventNotifier
*e
)
80 if (!e
->initialized
) {
84 if (e
->rfd
!= e
->wfd
) {
91 e
->initialized
= false;
94 int event_notifier_get_fd(const EventNotifier
*e
)
99 int event_notifier_get_wfd(const EventNotifier
*e
)
104 int event_notifier_set(EventNotifier
*e
)
106 static const uint64_t value
= 1;
109 if (!e
->initialized
) {
114 ret
= write(e
->wfd
, &value
, sizeof(value
));
115 } while (ret
< 0 && errno
== EINTR
);
117 /* EAGAIN is fine, a read must be pending. */
118 if (ret
< 0 && errno
!= EAGAIN
) {
124 int event_notifier_test_and_clear(EventNotifier
*e
)
130 if (!e
->initialized
) {
134 /* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
137 len
= read(e
->rfd
, buffer
, sizeof(buffer
));
139 } while ((len
== -1 && errno
== EINTR
) || len
== sizeof(buffer
));