Statistics
| Branch: | Revision:

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
}