]> Git Repo - qemu.git/blob - event_notifier-posix.c
target-i386: Postpone cpuid_level update to realize time
[qemu.git] / event_notifier-posix.c
1 /*
2  * event notifier support
3  *
4  * Copyright Red Hat, Inc. 2010
5  *
6  * Authors:
7  *  Michael S. Tsirkin <[email protected]>
8  *
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.
11  */
12
13 #include "qemu-common.h"
14 #include "event_notifier.h"
15 #include "qemu-char.h"
16
17 #ifdef CONFIG_EVENTFD
18 #include <sys/eventfd.h>
19 #endif
20
21 void event_notifier_init_fd(EventNotifier *e, int fd)
22 {
23     e->rfd = fd;
24     e->wfd = fd;
25 }
26
27 int event_notifier_init(EventNotifier *e, int active)
28 {
29     int fds[2];
30     int ret;
31
32 #ifdef CONFIG_EVENTFD
33     ret = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
34 #else
35     ret = -1;
36     errno = ENOSYS;
37 #endif
38     if (ret >= 0) {
39         e->rfd = e->wfd = ret;
40     } else {
41         if (errno != ENOSYS) {
42             return -errno;
43         }
44         if (qemu_pipe(fds) < 0) {
45             return -errno;
46         }
47         ret = fcntl_setfl(fds[0], O_NONBLOCK);
48         if (ret < 0) {
49             ret = -errno;
50             goto fail;
51         }
52         ret = fcntl_setfl(fds[1], O_NONBLOCK);
53         if (ret < 0) {
54             ret = -errno;
55             goto fail;
56         }
57         e->rfd = fds[0];
58         e->wfd = fds[1];
59     }
60     if (active) {
61         event_notifier_set(e);
62     }
63     return 0;
64
65 fail:
66     close(fds[0]);
67     close(fds[1]);
68     return ret;
69 }
70
71 void event_notifier_cleanup(EventNotifier *e)
72 {
73     if (e->rfd != e->wfd) {
74         close(e->rfd);
75     }
76     close(e->wfd);
77 }
78
79 int event_notifier_get_fd(EventNotifier *e)
80 {
81     return e->rfd;
82 }
83
84 int event_notifier_set_handler(EventNotifier *e,
85                                EventNotifierHandler *handler)
86 {
87     return qemu_set_fd_handler(e->rfd, (IOHandler *)handler, NULL, e);
88 }
89
90 int event_notifier_set(EventNotifier *e)
91 {
92     static const uint64_t value = 1;
93     ssize_t ret;
94
95     do {
96         ret = write(e->wfd, &value, sizeof(value));
97     } while (ret < 0 && errno == EINTR);
98
99     /* EAGAIN is fine, a read must be pending.  */
100     if (ret < 0 && errno != EAGAIN) {
101         return -errno;
102     }
103     return 0;
104 }
105
106 int event_notifier_test_and_clear(EventNotifier *e)
107 {
108     int value;
109     ssize_t len;
110     char buffer[512];
111
112     /* Drain the notify pipe.  For eventfd, only 8 bytes will be read.  */
113     value = 0;
114     do {
115         len = read(e->rfd, buffer, sizeof(buffer));
116         value |= (len > 0);
117     } while ((len == -1 && errno == EINTR) || len == sizeof(buffer));
118
119     return value;
120 }
This page took 0.030761 seconds and 4 git commands to generate.