From: Fam Zheng <famz@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PATCH v3 1/7] poll: Introduce QEMU Poll API
Date: Thu, 16 Apr 2015 12:57:30 +0800 [thread overview]
Message-ID: <1429160256-27231-2-git-send-email-famz@redhat.com> (raw)
In-Reply-To: <1429160256-27231-1-git-send-email-famz@redhat.com>
This is abstract of underlying poll implementation. A glib
implementation is included.
Signed-off-by: Fam Zheng <famz@redhat.com>
---
Makefile.objs | 2 +-
include/qemu/poll.h | 40 +++++++++++++++
include/qemu/typedefs.h | 4 +-
poll-glib.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 174 insertions(+), 2 deletions(-)
create mode 100644 include/qemu/poll.h
create mode 100644 poll-glib.c
diff --git a/Makefile.objs b/Makefile.objs
index 28999d3..77a56d0 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -9,7 +9,7 @@ util-obj-y = util/ qobject/ qapi/ qapi-types.o qapi-visit.o qapi-event.o
block-obj-y = async.o thread-pool.o
block-obj-y += nbd.o block.o blockjob.o
block-obj-y += main-loop.o iohandler.o qemu-timer.o
-block-obj-$(CONFIG_POSIX) += aio-posix.o
+block-obj-$(CONFIG_POSIX) += aio-posix.o poll-glib.o
block-obj-$(CONFIG_WIN32) += aio-win32.o
block-obj-y += block/
block-obj-y += qemu-io-cmds.o
diff --git a/include/qemu/poll.h b/include/qemu/poll.h
new file mode 100644
index 0000000..597975f
--- /dev/null
+++ b/include/qemu/poll.h
@@ -0,0 +1,40 @@
+#ifndef QEMU_POLL_H
+#define QEMU_POLL_H
+
+#include "qemu/typedefs.h"
+#include "qemu-common.h"
+
+struct QEMUPollEvent {
+ int fd;
+ int events;
+ int revents;
+ void *opaque;
+};
+
+QEMUPoll *qemu_poll_new(void);
+void qemu_poll_free(QEMUPoll *qpoll);
+int qemu_poll(QEMUPoll *qpoll, int64_t timeout_ns);
+
+/* Add an fd to poll. Return -EEXIST if fd already registered. */
+int qemu_poll_add(QEMUPoll *qpoll, int fd, int gio_events, void *opaque);
+
+/* Delete a previously added fd. Return -ENOENT if fd not registered. */
+int qemu_poll_del(QEMUPoll *qpoll, int fd);
+
+/**
+ * A shortcut to:
+ * 1) remove all the existing fds;
+ * 2) add all in @fds, while setting each fd's opaque pointer to the pollfd
+ * struct itself.
+ */
+int qemu_poll_set_fds(QEMUPoll *qpoll, GPollFD *fds, int nfds);
+
+/**
+ * Query the events from last qemu_poll. ONLY revent and opaque are valid in
+ * @events after return.
+ */
+int qemu_poll_get_events(QEMUPoll *qpoll,
+ QEMUPollEvent *events,
+ int max_events);
+
+#endif
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index cde3314..8e638cb 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -64,10 +64,12 @@ typedef struct QEMUBH QEMUBH;
typedef struct QemuConsole QemuConsole;
typedef struct QEMUFile QEMUFile;
typedef struct QEMUMachine QEMUMachine;
+typedef struct QEMUPoll QEMUPoll;
+typedef struct QEMUPollEvent QEMUPollEvent;
typedef struct QEMUSGList QEMUSGList;
typedef struct QEMUSizedBuffer QEMUSizedBuffer;
-typedef struct QEMUTimerListGroup QEMUTimerListGroup;
typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUTimerListGroup QEMUTimerListGroup;
typedef struct Range Range;
typedef struct SerialState SerialState;
typedef struct SHPCDevice SHPCDevice;
diff --git a/poll-glib.c b/poll-glib.c
new file mode 100644
index 0000000..64fde69
--- /dev/null
+++ b/poll-glib.c
@@ -0,0 +1,130 @@
+/*
+ * g_poll implementation for QEMU Poll API
+ *
+ * Copyright Red Hat, Inc. 2014
+ *
+ * Authors:
+ * Fam Zheng <famz@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qemu/timer.h"
+#include "qemu/poll.h"
+
+struct QEMUPoll {
+ /* Array of GPollFD for g_poll() */
+ GArray *gpollfds;
+
+ /* Array of opaque pointers, should be in sync with gpollfds */
+ GArray *opaque;
+};
+
+QEMUPoll *qemu_poll_new(void)
+{
+ QEMUPoll *qpoll = g_new0(QEMUPoll, 1);
+ qpoll->gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
+ qpoll->opaque = g_array_new(FALSE, FALSE, sizeof(void *));
+ return qpoll;
+}
+
+
+void qemu_poll_free(QEMUPoll *qpoll)
+{
+ g_array_unref(qpoll->gpollfds);
+ g_array_unref(qpoll->opaque);
+ g_free(qpoll);
+}
+
+int qemu_poll(QEMUPoll *qpoll, int64_t timeout_ns)
+{
+ int i;
+ for (i = 0; i < qpoll->gpollfds->len; i++) {
+ GPollFD *p = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ p->revents = 0;
+ }
+ return g_poll((GPollFD *)qpoll->gpollfds->data,
+ qpoll->gpollfds->len,
+ qemu_timeout_ns_to_ms(timeout_ns));
+}
+
+/* Add an fd to poll. Return -EEXIST if fd already registered. */
+int qemu_poll_add(QEMUPoll *qpoll, int fd, int gio_events, void *opaque)
+{
+ int i;
+ GPollFD pfd = (GPollFD) {
+ .fd = fd,
+ .revents = 0,
+ .events = gio_events,
+ };
+
+ for (i = 0; i < qpoll->gpollfds->len; i++) {
+ GPollFD *p = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ if (p->fd == fd) {
+ return -EEXIST;
+ }
+ }
+ g_array_append_val(qpoll->gpollfds, pfd);
+ g_array_append_val(qpoll->opaque, opaque);
+ assert(qpoll->gpollfds->len == qpoll->opaque->len);
+ return 0;
+}
+
+/* Delete a previously added fd. Return -ENOENT if fd not registered. */
+int qemu_poll_del(QEMUPoll *qpoll, int fd)
+{
+ int i;
+ int found = -1;
+
+ for (i = 0; i < qpoll->gpollfds->len; i++) {
+ GPollFD *p = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ if (p->fd == fd) {
+ found = i;
+ break;
+ }
+ }
+ if (found >= 0) {
+ g_array_remove_index(qpoll->gpollfds, found);
+ g_array_remove_index(qpoll->opaque, found);
+ assert(qpoll->gpollfds->len == qpoll->opaque->len);
+ return 0;
+ } else {
+ return -ENOENT;
+ }
+}
+
+int qemu_poll_set_fds(QEMUPoll *qpoll, GPollFD *fds, int nfds)
+{
+ int i;
+ g_array_set_size(qpoll->gpollfds, 0);
+ g_array_set_size(qpoll->opaque, 0);
+ for (i = 0; i < nfds; i++) {
+ void *opaque = &fds[i];
+ g_array_append_val(qpoll->gpollfds, fds[i]);
+ g_array_append_val(qpoll->opaque, opaque);
+ assert(qpoll->gpollfds->len == qpoll->opaque->len);
+ }
+ return nfds;
+}
+
+int qemu_poll_get_events(QEMUPoll *qpoll,
+ QEMUPollEvent *events,
+ int max_events)
+{
+ int i;
+ int r = 0;
+ for (i = 0; i < qpoll->gpollfds->len && r < max_events; i++) {
+ GPollFD *fd = &g_array_index(qpoll->gpollfds, GPollFD, i);
+ if (fd->revents & fd->events) {
+ events[r].fd = fd->fd;
+ events[r].revents = fd->revents;
+ events[r].events = fd->events;
+ events[r].opaque = g_array_index(qpoll->opaque, void *, i);
+ r++;
+ }
+ }
+ return r;
+}
--
1.9.3
next prev parent reply other threads:[~2015-04-16 4:57 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-16 4:57 [Qemu-devel] [PATCH v3 0/7] aio: Support epoll by introducing qemu_poll abstraction Fam Zheng
2015-04-16 4:57 ` Fam Zheng [this message]
2015-04-16 4:57 ` [Qemu-devel] [PATCH v3 2/7] posix-aio: Use QEMU poll interface Fam Zheng
2015-04-16 4:57 ` [Qemu-devel] [PATCH v3 3/7] poll: Add epoll implementation for qemu_poll Fam Zheng
2015-04-16 4:57 ` [Qemu-devel] [PATCH v3 4/7] main-loop: Replace qemu_poll_ns with qemu_poll Fam Zheng
2015-04-16 4:57 ` [Qemu-devel] [PATCH v3 5/7] tests: Add test case for qemu_poll Fam Zheng
2015-04-16 4:57 ` [Qemu-devel] [PATCH v3 6/7] poll-glib: Support ppoll Fam Zheng
2015-04-16 4:57 ` [Qemu-devel] [PATCH v3 7/7] poll-linux: Add timerfd support Fam Zheng
2015-04-16 13:00 ` Stefan Hajnoczi
2015-04-16 13:03 ` [Qemu-devel] [PATCH v3 0/7] aio: Support epoll by introducing qemu_poll abstraction Stefan Hajnoczi
2015-04-17 2:02 ` Fam Zheng
2015-04-20 10:36 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1429160256-27231-2-git-send-email-famz@redhat.com \
--to=famz@redhat.com \
--cc=kwolf@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).