[Qemu-devel] [PATCH 6/8] enable event_notifier to use pipes

2010-05-26 Thread Paolo Bonzini
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
---
 event_notifier.c |   69 +++---
 event_notifier.h |3 +-
 2 files changed, 52 insertions(+), 20 deletions(-)

diff --git a/event_notifier.c b/event_notifier.c
index 066adb9..a33f3c5 100644
--- a/event_notifier.c
+++ b/event_notifier.c
@@ -10,51 +10,82 @@
  * the COPYING file in the top-level directory.
  */
 
+#include qemu-common.h
 #include event_notifier.h
 #include qemu-char.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)
+int fds[2];
+int err;
+if (qemu_eventfd (fds)  0)
 return -errno;
-e-fd = fd;
+
+err = fcntl_setfl(fds[0], O_NONBLOCK);
+if (err  0)
+goto fail;
+
+err = fcntl_setfl(fds[1], O_NONBLOCK);
+if (err  0)
+goto fail;
+
+e-rfd = fds[0];
+e-wfd = fds[1];
+if (active)
+event_notifier_set(e);
 return 0;
-#else
-return -ENOSYS;
-#endif
+
+fail:
+close(fds[0]);
+close(fds[1]);
+return err;
 }
 
 void event_notifier_cleanup(EventNotifier *e)
 {
-close(e-fd);
+close(e-rfd);
+close(e-wfd);
 }
 
 int event_notifier_get_fd(EventNotifier *e)
 {
-return e-fd;
+return e-wfd;
 }
 
 int event_notifier_set_handler(EventNotifier *e,
EventNotifierHandler *handler)
 {
-return qemu_set_fd_handler(e-fd, (IOHandler *)handler, NULL, e);
+return qemu_set_fd_handler(e-rfd, (IOHandler *)handler, NULL, e);
 }
 
 int event_notifier_set(EventNotifier *e)
 {
-uint64_t value = 1;
-int r = write(e-fd, value, sizeof(value));
-return r == sizeof(value);
+static const uint64_t value = 1;
+ssize_t ret;
+
+do {
+ret = write(e-wfd, value, sizeof(value));
+} while (ret  0  errno == EINTR);
+
+/* EAGAIN is fine, a read must be pending.  */
+if (ret  0  errno != EAGAIN) {
+return -1;
+}
+return 0;
 }
 
 int event_notifier_test_and_clear(EventNotifier *e)
 {
-uint64_t value;
-int r = read(e-fd, value, sizeof(value));
-return r == sizeof(value);
+int value;
+ssize_t len;
+char buffer[512];
+
+/* Drain the notify pipe.  For eventfd, only 8 bytes will be read.  */
+value = 0;
+do {
+len = read(e-rfd, buffer, sizeof(buffer));
+value |= (len  0);
+} while ((len == -1  errno == EINTR) || len == sizeof(buffer));
+
+return value;
 }
diff --git a/event_notifier.h b/event_notifier.h
index f6ec9ef..ff9d6f2 100644
--- a/event_notifier.h
+++ b/event_notifier.h
@@ -4,7 +4,8 @@
 #include qemu-common.h
 
 struct EventNotifier {
-   int fd;
+int rfd;
+int wfd;
 };
 
 typedef void EventNotifierHandler(EventNotifier *);
-- 
1.6.6.1





Re: [Qemu-devel] [PATCH 6/8] enable event_notifier to use pipes

2010-05-26 Thread Richard Henderson
On 05/26/2010 07:09 AM, Paolo Bonzini wrote:
 -#ifdef CONFIG_EVENTFD
 -#include sys/eventfd.h
 -#endif

Is there a reason not to use eventfd if it is available?


r~