From patchwork Fri Oct 26 14:05:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 194502 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 12B382C00A3 for ; Sat, 27 Oct 2012 01:54:12 +1100 (EST) Received: from localhost ([::1]:34693 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TRkcR-00088B-32 for incoming@patchwork.ozlabs.org; Fri, 26 Oct 2012 10:10:39 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43521) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TRkbQ-0005kb-D3 for qemu-devel@nongnu.org; Fri, 26 Oct 2012 10:09:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TRkbK-0005V6-2t for qemu-devel@nongnu.org; Fri, 26 Oct 2012 10:09:36 -0400 Received: from mail-bk0-f45.google.com ([209.85.214.45]:61615) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TRkbJ-0005Sp-SA for qemu-devel@nongnu.org; Fri, 26 Oct 2012 10:09:30 -0400 Received: by mail-bk0-f45.google.com with SMTP id jf3so1090170bkc.4 for ; Fri, 26 Oct 2012 07:09:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=61/e/OZJpwCNysMVmvnwIJeGl+e4xTx/MW4t2gPEDKM=; b=R6w0x3kOEs1an3Z5WtLRJci8kGEJozsNx2EeWWxjS0gHCvYxPNOaGwIShImAcYTzk1 VZrIui7ZzMc3RFrLP18/W4cXg3LMN8TwFqy1gy4LRgpB4kaTUfYiS+xL3L7BX//+p5OC H5c+J5r63eAPOOPE5HvH3GDC8GY6yq3YQjxU6qNHCrhd/ptjwVWaXX7zcmn3n4YcnLeu 9aspfwUuLfUlf2FD7ypzHP/ZOa7iXaijkSOWtegnqJ6s6PPQn6nGmiXA1DqvVSuwbCpT iRMNOrlz4Mg3J3eQR02WAoQPN2WUltiXgSskd6zKzsj+8giAVHHUHZZAIasIN3LGmwmb +4OQ== Received: by 10.204.145.129 with SMTP id d1mr7081593bkv.31.1351260569487; Fri, 26 Oct 2012 07:09:29 -0700 (PDT) Received: from yakj.usersys.redhat.com (nat-pool-mxp-t.redhat.com. [209.132.186.18]) by mx.google.com with ESMTPS id s20sm1082468bkw.15.2012.10.26.07.09.28 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 26 Oct 2012 07:09:28 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 26 Oct 2012 16:05:32 +0200 Message-Id: <1351260355-19802-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.12.1 In-Reply-To: <1351260355-19802-1-git-send-email-pbonzini@redhat.com> References: <1351260355-19802-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.214.45 Cc: aliguori@us.ibm.com, stefanha@redhat.com Subject: [Qemu-devel] [PATCH 02/25] event_notifier: enable it to use pipes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This takes the eventfd emulation code from the main loop. 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. The return value of event_notifier_set changes to the cleaner 0/-errno. No caller is actually checking the return value. Reviewed-by: Anthony Liguori Signed-off-by: Paolo Bonzini --- event_notifier-posix.c | 85 ++++++++++++++++++++++++++++++++++++++++---------- event_notifier.h | 3 +- 2 file modificati, 71 inserzioni(+), 17 rimozioni(-) diff --git a/event_notifier-posix.c b/event_notifier-posix.c index 2c207e1..6f3239a 100644 --- a/event_notifier-posix.c +++ b/event_notifier-posix.c @@ -20,48 +20,101 @@ 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, EFD_NONBLOCK | EFD_CLOEXEC); #else - return -ENOSYS; + ret = -1; + errno = ENOSYS; #endif + if (ret >= 0) { + e->rfd = e->wfd = ret; + } else { + if (errno != ENOSYS) { + return -errno; + } + if (qemu_pipe(fds) < 0) { + return -errno; + } + ret = fcntl_setfl(fds[0], O_NONBLOCK); + if (ret < 0) { + ret = -errno; + goto fail; + } + ret = fcntl_setfl(fds[1], O_NONBLOCK); + if (ret < 0) { + ret = -errno; + goto fail; + } + e->rfd = fds[0]; + e->wfd = fds[1]; + } + if (active) { + event_notifier_set(e); + } + 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 -errno; + } + 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 b283a49..88b57af 100644 --- a/event_notifier.h +++ b/event_notifier.h @@ -23,7 +23,8 @@ struct EventNotifier { #ifdef _WIN32 HANDLE event; #else - int fd; + int rfd; + int wfd; #endif };