From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:44616) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Srvva-0003dW-NO for qemu-devel@nongnu.org; Thu, 19 Jul 2012 14:58:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SrvvZ-00016j-AW for qemu-devel@nongnu.org; Thu, 19 Jul 2012 14:58:22 -0400 Received: from mail-yx0-f173.google.com ([209.85.213.173]:49427) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrvvZ-00016a-5E for qemu-devel@nongnu.org; Thu, 19 Jul 2012 14:58:21 -0400 Received: by yenl1 with SMTP id l1so3250397yen.4 for ; Thu, 19 Jul 2012 11:58:20 -0700 (PDT) From: Anthony Liguori In-Reply-To: <1342435377-25897-2-git-send-email-pbonzini@redhat.com> References: <1342435377-25897-1-git-send-email-pbonzini@redhat.com> <1342435377-25897-2-git-send-email-pbonzini@redhat.com> Date: Thu, 19 Jul 2012 13:58:17 -0500 Message-ID: <87mx2v7f3q.fsf@codemonkey.ws> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Subject: Re: [Qemu-devel] [PATCH 01/12] event_notifier: enable it to use pipes List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini , qemu-devel@nongnu.org Cc: kwolf@redhat.com, aliguori@linux.vnet.ibm.com, stefanha@linux.vnet.ibm.com, sw@weilnetz.de Paolo Bonzini writes: > This takes the eventfd emulation code from the main loop and adds it > to EventNotifier. When the EventNotifier is used for the main loop too, > we need this compatibility code. > > Without CONFIG_EVENTFD, event_notifier_get_fd is only usable for the > "read" side of the notifier, for example to set a select() handler. > > Signed-off-by: Paolo Bonzini > --- > event_notifier.c | 83 +++++++++++++++++++++++++++++++++++++++++++----------- > event_notifier.h | 3 +- > 2 files changed, 69 insertions(+), 17 deletions(-) > > diff --git a/event_notifier.c b/event_notifier.c > index 2c207e1..dde2d32 100644 > --- a/event_notifier.c > +++ b/event_notifier.c > @@ -20,48 +20,99 @@ > > void event_notifier_init_fd(EventNotifier *e, int fd) > { > - e->fd = fd; > + e->rfd = fd; > + e->wfd = fd; > } > > int event_notifier_init(EventNotifier *e, int active) > { > + int fds[2]; > + int ret; > + > #ifdef CONFIG_EVENTFD > - int fd = eventfd(!!active, EFD_NONBLOCK | EFD_CLOEXEC); > - if (fd < 0) > - return -errno; > - e->fd = fd; > - return 0; > + ret = eventfd(0, O_NONBLOCK); > #else > - return -ENOSYS; > + ret = -1; > + errno = ENOSYS; > #endif > + if (ret >= 0) { > + e->rfd = e->wfd = ret; > + qemu_set_cloexec(ret); This is kind of redundant with EFD_CLOEXEC, no? > + } else { > + if (errno != ENOSYS) { > + return -errno; > + } > + if (qemu_pipe(fds) < 0) { > + return -errno; > + } > + ret = fcntl_setfl(fds[0], O_NONBLOCK); > + if (ret < 0) { > + goto fail; > + } > + ret = fcntl_setfl(fds[1], O_NONBLOCK); > + if (ret < 0) { > + goto fail; > + } > + e->rfd = fds[0]; > + e->wfd = fds[1]; > + } > + if (active) > + event_notifier_set(e); Missing a curly.. The rest looks good. Regards, Anthony Liguori > + return 0; > + > +fail: > + close(fds[0]); > + close(fds[1]); > + return ret; > } > > void event_notifier_cleanup(EventNotifier *e) > { > - close(e->fd); > + if (e->rfd != e->wfd) { > + close(e->rfd); > + } > + close(e->wfd); > } > > int event_notifier_get_fd(EventNotifier *e) > { > - return e->fd; > + return e->rfd; > } > > 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 f0ec2f2..f04d12d 100644 > --- a/event_notifier.h > +++ b/event_notifier.h > @@ -16,7 +16,8 @@ > #include "qemu-common.h" > > struct EventNotifier { > - int fd; > + int rfd; > + int wfd; > }; > > typedef void EventNotifierHandler(EventNotifier *); > -- > 1.7.10.4