root / event_notifier-posix.c @ cb9c377f
History | View | Annotate | Download (2.4 kB)
1 | 2292b339 | Michael S. Tsirkin | /*
|
---|---|---|---|
2 | 2292b339 | Michael S. Tsirkin | * event notifier support
|
3 | 2292b339 | Michael S. Tsirkin | *
|
4 | 2292b339 | Michael S. Tsirkin | * Copyright Red Hat, Inc. 2010
|
5 | 2292b339 | Michael S. Tsirkin | *
|
6 | 2292b339 | Michael S. Tsirkin | * Authors:
|
7 | 2292b339 | Michael S. Tsirkin | * Michael S. Tsirkin <mst@redhat.com>
|
8 | 2292b339 | Michael S. Tsirkin | *
|
9 | 6b620ca3 | Paolo Bonzini | * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
10 | 6b620ca3 | Paolo Bonzini | * See the COPYING file in the top-level directory.
|
11 | 2292b339 | Michael S. Tsirkin | */
|
12 | 2292b339 | Michael S. Tsirkin | |
13 | e80c262b | Paolo Bonzini | #include "qemu-common.h" |
14 | 2292b339 | Michael S. Tsirkin | #include "event_notifier.h" |
15 | 6bf819f0 | Paolo Bonzini | #include "qemu-char.h" |
16 | 077805fa | Paolo Bonzini | #include "main-loop.h" |
17 | e80c262b | Paolo Bonzini | |
18 | 2292b339 | Michael S. Tsirkin | #ifdef CONFIG_EVENTFD
|
19 | 2292b339 | Michael S. Tsirkin | #include <sys/eventfd.h> |
20 | 2292b339 | Michael S. Tsirkin | #endif
|
21 | 2292b339 | Michael S. Tsirkin | |
22 | e80c262b | Paolo Bonzini | void event_notifier_init_fd(EventNotifier *e, int fd) |
23 | e80c262b | Paolo Bonzini | { |
24 | d0cc2fbf | Paolo Bonzini | e->rfd = fd; |
25 | d0cc2fbf | Paolo Bonzini | e->wfd = fd; |
26 | e80c262b | Paolo Bonzini | } |
27 | e80c262b | Paolo Bonzini | |
28 | 2292b339 | Michael S. Tsirkin | int event_notifier_init(EventNotifier *e, int active) |
29 | 2292b339 | Michael S. Tsirkin | { |
30 | d0cc2fbf | Paolo Bonzini | int fds[2]; |
31 | d0cc2fbf | Paolo Bonzini | int ret;
|
32 | d0cc2fbf | Paolo Bonzini | |
33 | 2292b339 | Michael S. Tsirkin | #ifdef CONFIG_EVENTFD
|
34 | d0cc2fbf | Paolo Bonzini | ret = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
|
35 | 2292b339 | Michael S. Tsirkin | #else
|
36 | d0cc2fbf | Paolo Bonzini | ret = -1;
|
37 | d0cc2fbf | Paolo Bonzini | errno = ENOSYS; |
38 | 2292b339 | Michael S. Tsirkin | #endif
|
39 | d0cc2fbf | Paolo Bonzini | if (ret >= 0) { |
40 | d0cc2fbf | Paolo Bonzini | e->rfd = e->wfd = ret; |
41 | d0cc2fbf | Paolo Bonzini | } else {
|
42 | d0cc2fbf | Paolo Bonzini | if (errno != ENOSYS) {
|
43 | d0cc2fbf | Paolo Bonzini | return -errno;
|
44 | d0cc2fbf | Paolo Bonzini | } |
45 | d0cc2fbf | Paolo Bonzini | if (qemu_pipe(fds) < 0) { |
46 | d0cc2fbf | Paolo Bonzini | return -errno;
|
47 | d0cc2fbf | Paolo Bonzini | } |
48 | d0cc2fbf | Paolo Bonzini | ret = fcntl_setfl(fds[0], O_NONBLOCK);
|
49 | d0cc2fbf | Paolo Bonzini | if (ret < 0) { |
50 | d0cc2fbf | Paolo Bonzini | ret = -errno; |
51 | d0cc2fbf | Paolo Bonzini | goto fail;
|
52 | d0cc2fbf | Paolo Bonzini | } |
53 | d0cc2fbf | Paolo Bonzini | ret = fcntl_setfl(fds[1], O_NONBLOCK);
|
54 | d0cc2fbf | Paolo Bonzini | if (ret < 0) { |
55 | d0cc2fbf | Paolo Bonzini | ret = -errno; |
56 | d0cc2fbf | Paolo Bonzini | goto fail;
|
57 | d0cc2fbf | Paolo Bonzini | } |
58 | d0cc2fbf | Paolo Bonzini | e->rfd = fds[0];
|
59 | d0cc2fbf | Paolo Bonzini | e->wfd = fds[1];
|
60 | d0cc2fbf | Paolo Bonzini | } |
61 | d0cc2fbf | Paolo Bonzini | if (active) {
|
62 | d0cc2fbf | Paolo Bonzini | event_notifier_set(e); |
63 | d0cc2fbf | Paolo Bonzini | } |
64 | d0cc2fbf | Paolo Bonzini | return 0; |
65 | d0cc2fbf | Paolo Bonzini | |
66 | d0cc2fbf | Paolo Bonzini | fail:
|
67 | d0cc2fbf | Paolo Bonzini | close(fds[0]);
|
68 | d0cc2fbf | Paolo Bonzini | close(fds[1]);
|
69 | d0cc2fbf | Paolo Bonzini | return ret;
|
70 | 2292b339 | Michael S. Tsirkin | } |
71 | 2292b339 | Michael S. Tsirkin | |
72 | 2292b339 | Michael S. Tsirkin | void event_notifier_cleanup(EventNotifier *e)
|
73 | 2292b339 | Michael S. Tsirkin | { |
74 | d0cc2fbf | Paolo Bonzini | if (e->rfd != e->wfd) {
|
75 | d0cc2fbf | Paolo Bonzini | close(e->rfd); |
76 | d0cc2fbf | Paolo Bonzini | } |
77 | d0cc2fbf | Paolo Bonzini | close(e->wfd); |
78 | 2292b339 | Michael S. Tsirkin | } |
79 | 2292b339 | Michael S. Tsirkin | |
80 | 2292b339 | Michael S. Tsirkin | int event_notifier_get_fd(EventNotifier *e)
|
81 | 2292b339 | Michael S. Tsirkin | { |
82 | d0cc2fbf | Paolo Bonzini | return e->rfd;
|
83 | 2292b339 | Michael S. Tsirkin | } |
84 | 2292b339 | Michael S. Tsirkin | |
85 | 6bf819f0 | Paolo Bonzini | int event_notifier_set_handler(EventNotifier *e,
|
86 | 6bf819f0 | Paolo Bonzini | EventNotifierHandler *handler) |
87 | 6bf819f0 | Paolo Bonzini | { |
88 | d0cc2fbf | Paolo Bonzini | return qemu_set_fd_handler(e->rfd, (IOHandler *)handler, NULL, e); |
89 | 6bf819f0 | Paolo Bonzini | } |
90 | 6bf819f0 | Paolo Bonzini | |
91 | 2ec10b95 | Paolo Bonzini | int event_notifier_set(EventNotifier *e)
|
92 | 2ec10b95 | Paolo Bonzini | { |
93 | d0cc2fbf | Paolo Bonzini | static const uint64_t value = 1; |
94 | d0cc2fbf | Paolo Bonzini | ssize_t ret; |
95 | d0cc2fbf | Paolo Bonzini | |
96 | d0cc2fbf | Paolo Bonzini | do {
|
97 | d0cc2fbf | Paolo Bonzini | ret = write(e->wfd, &value, sizeof(value));
|
98 | d0cc2fbf | Paolo Bonzini | } while (ret < 0 && errno == EINTR); |
99 | d0cc2fbf | Paolo Bonzini | |
100 | d0cc2fbf | Paolo Bonzini | /* EAGAIN is fine, a read must be pending. */
|
101 | d0cc2fbf | Paolo Bonzini | if (ret < 0 && errno != EAGAIN) { |
102 | d0cc2fbf | Paolo Bonzini | return -errno;
|
103 | d0cc2fbf | Paolo Bonzini | } |
104 | d0cc2fbf | Paolo Bonzini | return 0; |
105 | 2ec10b95 | Paolo Bonzini | } |
106 | 2ec10b95 | Paolo Bonzini | |
107 | 2292b339 | Michael S. Tsirkin | int event_notifier_test_and_clear(EventNotifier *e)
|
108 | 2292b339 | Michael S. Tsirkin | { |
109 | d0cc2fbf | Paolo Bonzini | int value;
|
110 | d0cc2fbf | Paolo Bonzini | ssize_t len; |
111 | d0cc2fbf | Paolo Bonzini | char buffer[512]; |
112 | d0cc2fbf | Paolo Bonzini | |
113 | d0cc2fbf | Paolo Bonzini | /* Drain the notify pipe. For eventfd, only 8 bytes will be read. */
|
114 | d0cc2fbf | Paolo Bonzini | value = 0;
|
115 | d0cc2fbf | Paolo Bonzini | do {
|
116 | d0cc2fbf | Paolo Bonzini | len = read(e->rfd, buffer, sizeof(buffer));
|
117 | d0cc2fbf | Paolo Bonzini | value |= (len > 0);
|
118 | d0cc2fbf | Paolo Bonzini | } while ((len == -1 && errno == EINTR) || len == sizeof(buffer)); |
119 | d0cc2fbf | Paolo Bonzini | |
120 | d0cc2fbf | Paolo Bonzini | return value;
|
121 | 2292b339 | Michael S. Tsirkin | } |