| /* |
| * event notifier support |
| * |
| * Copyright Red Hat, Inc. 2010 |
| * |
| * Authors: |
| * Michael S. Tsirkin <mst@redhat.com> |
| * |
| * This work is licensed under the terms of the GNU GPL, version 2. See |
| * the COPYING file in the top-level directory. |
| */ |
| |
| #include "hw.h" |
| #include "event_notifier.h" |
| #ifdef CONFIG_EVENTFD |
| #include <sys/eventfd.h> |
| #endif |
| |
| int event_notifier_init(EventNotifier *e, int active) |
| { |
| #ifdef CONFIG_EVENTFD |
| int fd = eventfd(!!active, EFD_NONBLOCK | EFD_CLOEXEC); |
| if (fd < 0) |
| return -errno; |
| e->fd = fd; |
| return 0; |
| #else |
| return -ENOSYS; |
| #endif |
| } |
| |
| void event_notifier_cleanup(EventNotifier *e) |
| { |
| close(e->fd); |
| } |
| |
| int event_notifier_get_fd(EventNotifier *e) |
| { |
| return e->fd; |
| } |
| |
| int event_notifier_test_and_clear(EventNotifier *e) |
| { |
| uint64_t value; |
| int r = read(e->fd, &value, sizeof(value)); |
| return r == sizeof(value); |
| } |
| |
| int event_notifier_test(EventNotifier *e) |
| { |
| uint64_t value; |
| int r = read(e->fd, &value, sizeof(value)); |
| if (r == sizeof(value)) { |
| /* restore previous value. */ |
| int s = write(e->fd, &value, sizeof(value)); |
| /* never blocks because we use EFD_SEMAPHORE. |
| * If we didn't we'd get EAGAIN on overflow |
| * and we'd have to write code to ignore it. */ |
| assert(s == sizeof(value)); |
| } |
| return r == sizeof(value); |
| } |