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